hotspot/src/os/windows/vm/threadCritical_windows.cpp
ThreadCritical::ThreadCritical() {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
DWORD current_thread = GetCurrentThreadId();
{- -------------------------------------------
(1) 現在ロックを保持しているのがカレントスレッドでなければ,
次の if ブロック内でロックの確保を行う.
---------------------------------------- -}
if (lock_owner != current_thread) {
{- -------------------------------------------
(1.1) Atomic::cmpxchg() でロックの確保を行う (= lock_count を -1 から 0 に書き換える).
(失敗したら WaitForSingleObject() で待機し, 成功するまで繰り返す.
ただし, 初回の呼び出し時には,
ロック待ち用のイベントオブジェクトがまだできていないので
Atomic::cmpxchg() だけを繰り返す)
---------------------------------------- -}
// Grab the lock before doing anything.
while (Atomic::cmpxchg(0, &lock_count, -1) != -1) {
if (initialized) {
DWORD ret = WaitForSingleObject(lock_event, INFINITE);
assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
}
}
{- -------------------------------------------
(1.1) これが初回の呼び出し時であれば, CreateEvent() を呼んで
ロック待ち用のイベントオブジェクトを生成しておく.
---------------------------------------- -}
// Make sure the event object is allocated.
if (!initialized) {
// Locking will not work correctly unless this is autoreset.
lock_event = CreateEvent(NULL, false, false, NULL);
initialized = true;
}
{- -------------------------------------------
(1.1) (assert)
---------------------------------------- -}
assert(lock_owner == -1, "Lock acquired illegally.");
{- -------------------------------------------
(1.1) ロック保持者を示す変数(lock_owner)にカレントスレッドをセットする.
---------------------------------------- -}
lock_owner = current_thread;
{- -------------------------------------------
(1) 現在ロックを保持しているのがカレントスレッドであれば,
ロックの再帰確保数をインクリメントするだけ.
---------------------------------------- -}
} else {
// Atomicity isn't required. Bump the recursion count.
lock_count++;
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(lock_owner == GetCurrentThreadId(), "Lock acquired illegally.");
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.