Up Top

Thread の待機処理の枠組み : ThreadCritical による処理


概要(Summary)

これは, 非常に簡単な critical section に対してのみ使用される Mutex 実装. なお, 他の待機処理用のクラスに比べて使用箇所は少ない.

HotSpot の初期化作業のかなり早い段階でも使われるため, ParkEvent (os::PlatformEvent) は使用せず独自の排他処理を行っている.

内部的には, 対応する mutex を大域に 1つだけ保持しており, その mutex に対する排他処理(ロックの確保/開放処理)を行う (See: ThreadCritical).

ThreadCritical クラスは以下のように使用する.

  1. ThreadCritical::initialize() で, 大域的な初期化を行っておく (これは最初に 1回実行すればいい).

  2. ThreadCritical 型の局所変数を宣言する.

コンストラクタでロックが確保され, デストラクタでロックが解放される.

備考(Notes)

Solaris 上での実装について

コメントによると, 「os::init() が完了するまではロックが機能しないようになっているが, 理由が分からないので後でレビューが必要」. とのこと.

    ((cite: hotspot/src/os/solaris/vm/threadCritical_solaris.cpp))
    // For some reason, we don't do locking until the
    // os::init() call completes. I'm not sure why this
    // is, and have left it that way for now. This should
    // be reviewed later.

Windows 上での実装について

コメントによると, 「Microsoft の critical region code (Win32 の CRITICAL_SECTION のこと?? #TODO) には race condition が存在するので使えない」, とのこと (<= どういうこと?? #TODO).

また, Win32 の Mutex は critical region code の 30 倍くらい遅いので使えない, とも. (<= まぁあれはスレッド間の同期というよりプロセス間通信用だし...)

    ((cite: hotspot/src/os/windows/vm/threadCritical_windows.cpp))
    //
    // Note that Microsoft's critical region code contains a race
    // condition, and is not suitable for use. A thread holding the
    // critical section cannot safely suspend a thread attempting
    // to enter the critical region. The failure mode is that both
    // threads are permanently suspended.
    //
    // I experiemented with the use of ordinary windows mutex objects
    // and found them ~30 times slower than the critical region code.
    //

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

ThreadCritical クラスの初期化処理

(HotSpot の起動時処理) (See: here for details)
-> Threads::create_vm()
   -> os::init()
      -> ThreadCritical::initialize()   (← ただし Solaris または Linux の場合にのみ呼び出されている)

ThreadCritical オブジェクトによるロック処理

ThreadCritical::ThreadCritical()
-> OS によって処理が異なる.
   * Linux の場合
     -> pthread_mutex_lock()
   * Solaris の場合
     -> os::Solaris::mutex_lock()
        -> _lwp_mutex_lock() or pthread_mutex_lock() or mutex_lock()
   * Windows の場合
     -> Atomic::cmpxchg()
     -> WaitForSingleObject()
     -> CreateEvent()          (← 初回の呼び出し時のみ)

ThreadCritical::~ThreadCritical()
-> OS によって処理が異なる.
   * Linux の場合
     -> pthread_mutex_unlock()
   * Solaris の場合
     -> os::Solaris::mutex_unlock()
        -> _lwp_mutex_unlock() or pthread_mutex_unlock() or mutex_unlock()
   * Windows の場合
     -> SetEvent()

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

ThreadCritical::initialize() (Linux の場合)

See: here for details

ThreadCritical::release() (Linux の場合)

See: here for details (この関数は使われていないような... #TODO)

ThreadCritical::ThreadCritical() (Linux の場合)

See: here for details

ThreadCritical::~ThreadCritical() (Linux の場合)

See: here for details

ThreadCritical::initialize() (Solaris の場合)

See: here for details

ThreadCritical::release() (Solaris の場合)

See: here for details (この関数は使われていないような... #TODO)

ThreadCritical::ThreadCritical() (Solaris の場合)

See: here for details

os::Solaris::mutex_lock()

See: here for details

ThreadCritical::~ThreadCritical() (Solaris の場合)

See: here for details

os::Solaris::mutex_unlock()

See: here for details

ThreadCritical::initialize() (Windows の場合)

See: here for details (この関数は使われていないような... #TODO)

ThreadCritical::release() (Windows の場合)

See: here for details (この関数は使われていないような... #TODO)

ThreadCritical::ThreadCritical() (Windows の場合)

See: here for details

ThreadCritical::~ThreadCritical() (Windows の場合)

See: here for details


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