Up Top

Thread の待機処理の枠組み : Mutex, Monitor による処理


概要(Summary)

これらは ParkEvent 及び SpinLock, Mux を用いて構築された Mutex 及びモニタ実装. 長い critical section にも利用できる (See: Mutex, Monitor).

内部的には, 各 Thread オブジェクトが _MutexEvent というフィールドに ParkEvent オブジェクトを保持している. これが Mutex や Monitor の処理 (lock/unlock, wait/notify/notifyAll) で使用される.

Monitor::IWait() で寝る前に Notified をゼロにしておき, Monitor::notify() で起こした対象の Notified を 1 にする. 起きたスレッドは, Notified がゼロのままなら再び眠りにつく.

処理の流れ (概要)(Execution Flows : Summary)

Monitor::lock() (Mutex::lock())

Monitor::lock()
-> Monitor::TryFast()           (成功すれば, ここでリターン)
-> Monitor::TrySpin()           (成功すれば, ここでリターン)
   -> Monitor::TryLock()        (成功すれば, ここでリターン)
   -> 適当な回数だけ CAS によるロックを試みる.
      -> CASPTR() マクロ
      -> SpinPause() で時間をつぶす
      -> MarsagliaXORV() 又は Stall() で時間をつぶす
-> Monitor::ILock()
   -> Monitor::TryFast()        (成功すれば, ここでリターン)
   -> Monitor::TrySpin()        (成功すれば, ここでリターン)
   -> Monitor::AcquireOrPush()  (成功すれば, ここでリターン) (失敗した場合は, 待ち行列に追加される)
   -> ParkCommon() で待機する. この中では以下のどちらかを呼び出す
      * タイムアウト時間が指定されていない場合
        -> os::PlatformEvent::park()
      * タイムアウト時間が指定されている場合
        -> os::PlatformEvent::park(jlong millis)
   -> Monitor::TrySpin()

Monitor::unlock() (Mutex::unlock())

Monitor::unlock()
-> Monitor::IUnlock()

Monitor::wait()

Monitor::wait()
-> Monitor::IWait()
   -> カレントスレッドを _WaitSet に登録する
   -> Monitor::IUnlock()
   -> ParkCommon()
   -> Monitor::ILock()

Monitor::notify()

Monitor::notify()
-> _WaitSet の先頭のスレッドを cxq に移動させる
   (これで Monitor::notify() を呼んだスレッドが unlock した際 (あるいはそれ以降の unlock() 時) に unpark() されるようになる)

Monitor::notify_all()

Monitor::notify_all()
-> Monitor::notify()  (← wait しているスレッド数分だけ呼び出す)
   -> (上述)

処理の流れ (詳細)(Execution Flows : Details)

Mutex::lock()

See: here for details

Monitor::lock(Thread * Self)

See: here for details

Monitor::TryFast()

See: here for details

CASPTR() マクロ

See: here for details

Monitor::set_owner()

See: here for details

Monitor::TrySpin()

See: here for details

Monitor::TryLock()

See: here for details

MarsagliaXORV()

See: here for details

Stall()

See: here for details

Monitor::ILock()

See: here for details

UNS() マクロ

See: here for details

Monitor::AcquireOrPush()

See: here for details

ParkCommon()

See: here for details

Mutex::unlock()

See: here for details

Monitor::IUnlock()

See: here for details

Monitor::wait()

See: here for details

Monitor::IWait()

See: here for details

Monitor::notify()

See: here for details

Monitor::notify_all()

See: here for details


This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.