hotspot/src/os/solaris/vm/os_solaris.cpp
void os::interrupt(Thread* thread) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
OSThread* osthread = thread->osthread();
{- -------------------------------------------
(1) 対象スレッドの _SleepEvent フィールドにある ParkEvent オブジェクトに対して
os::PlatformEvent::unpark() を呼び出しておく.
(これは java.lang.Thread.sleep() に割り込むための処理.
See: java.lang.Thread.sleep())
ただし, 既に対象のスレッドが割り込まれていた場合には, この処理は行わない.
この確認処理も含めて, 処理は以下の順で行う.
(1) OSThread::interrupted() で, 処理対象のスレッドの interrupted フラグを確認.
(2) OSThread::set_interrupted() で, 処理対象のスレッドの interrupted フラグを立てる.
(3) OrderAccess::fence() でメモリバリアを張り,
この後の load/store よりも先に interrupted フラグの変更が visible になるようにしておく.
(4) os::PlatformEvent::unpark() を呼び出す.
なお, os::sleep() の待機処理は, _SleepEvent に対する park() ではなく, poll() になっていることもある.
ただし, poll() のケースについては後の thr_kill() で割り込むので問題ない.
---------------------------------------- -}
int isInterrupted = osthread->interrupted();
if (!isInterrupted) {
osthread->set_interrupted(true);
OrderAccess::fence();
// os::sleep() is implemented with either poll (NULL,0,timeout) or
// by parking on _SleepEvent. If the former, thr_kill will unwedge
// the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper.
ParkEvent * const slp = thread->_SleepEvent ;
if (slp != NULL) slp->unpark() ;
}
{- -------------------------------------------
(1) もし対象のスレッドが JavaThread であれば,
JavaThread::parker() で Parker オブジェクトを取得して
Parker::unpark() を呼び出しておく.
(これは, java.util.concurrent.locks.LockSupport.park() に割り込むための処理.
See: java.util.concurrent.locks.LockSupport.park())
---------------------------------------- -}
// For JSR166: unpark after setting status but before thr_kill -dl
if (thread->is_Java_thread()) {
((JavaThread*)thread)->parker()->unpark();
}
{- -------------------------------------------
(1) もし対象のスレッドの _ParkEvent フィールドに
ParkEvent オブジェクトが入っていれば (= NULL でなければ),
それに対しても os::PlatformEvent::unpark() を呼び出しておく.
(これは, java.lang.Object.wait() に割り込むための処理.
See: java.lang.Object.wait())
---------------------------------------- -}
// Handle interruptible wait() ...
ParkEvent * const ev = thread->_ParkEvent ;
if (ev != NULL) ev->unpark() ;
{- -------------------------------------------
(1) 上で調べた際に対象スレッドが割り込まれていなかった場合には,
thr_kill() でシグナルも送っておく.
(これは os::sleep() に割り込むための処理. 上述)
(ついでに(プロファイル情報の記録)も行っている.
See: RuntimeService)
---------------------------------------- -}
// When events are used everywhere for os::sleep, then this thr_kill
// will only be needed if UseVMInterruptibleIO is true.
if (!isInterrupted) {
int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt());
assert_status(status == 0, status, "thr_kill");
// Bump thread interruption counter
RuntimeService::record_thread_interrupt_signaled_count();
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.