hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp
int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
guarantee (_owner == Self, "invariant") ;
{- -------------------------------------------
(1) もし _WaitSet も誰もいなければ, 何もすることはないので, ここでリターン.
---------------------------------------- -}
if (_WaitSet == NULL) return OS_OK ;
{- -------------------------------------------
(1) (ここでの処理には2つの方式が考えられるが, 現在は B. を採用している, とのこと.
A. WaitSet の中身を EntryList に移すだけにする
B. WaitSet の中身を取り出し unpark() まで行う
ただし, 余りいい方法ではなく futile context switing や contention が多発する. とのこと.)
---------------------------------------- -}
// We have two options:
// A. Transfer the threads from the WaitSet to the EntryList
// B. Remove the thread from the WaitSet and unpark() it.
//
// We use (B), which is crude and results in lots of futile
// context switching. In particular (B) induces lots of contention.
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
ParkEvent * ev = NULL ; // consider using a small auto array ...
{- -------------------------------------------
(1) 以下の for ループの中で, _WaitSet 中の ObjectWaiter に対して,
その TState を ObjectWaiter::TS_RUN に変更し (てメモリバリアも張っ) た後,
os::PlatformEvent::unpark() で起床させている.
All 引数が false の場合は, 最初の一個だけで処理は終了.
All 引数が true の場合は, 全部の ObjectWaiter に対して処理を行う.
(なお, ループの処理が少し変則的で, 最後の一個はループ外で起床させる形になる)
(また, このループの処理は RawMonitor_lock で排他した状態で行う)
---------------------------------------- -}
RawMonitor_lock->lock_without_safepoint_check() ;
for (;;) {
ObjectWaiter * w = _WaitSet ;
if (w == NULL) break ;
_WaitSet = w->_next ;
if (ev != NULL) { ev->unpark(); ev = NULL; }
ev = w->_event ;
OrderAccess::loadstore() ;
w->TState = ObjectWaiter::TS_RUN ;
OrderAccess::storeload();
if (!All) break ;
}
RawMonitor_lock->unlock() ;
{- -------------------------------------------
(1) 最後の一個を os::PlatformEvent::unpark() で起床させる.
---------------------------------------- -}
if (ev != NULL) ev->unpark();
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return OS_OK ;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.