hotspot/src/os/windows/vm/os_windows.cpp
/*
* The Windows implementation of Park is very straightforward: Basic
* operations on Win32 Events turn out to have the right semantics to
* use them directly. We opportunistically resuse the event inherited
* from Monitor.
*/
void Parker::park(bool isAbsolute, jlong time) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
guarantee (_ParkEvent != NULL, "invariant") ;
{- -------------------------------------------
(1) 初めに, 指定された待ち時間の値(time)を調整しておく.
* 指定が絶対時間で, かつ値が 0 の場合
INFINITE とする
* 指定が絶対時間で, 値が 0 以外の場合
現在時刻からの相対時間に修正する
* 指定が相対時間の場合
1000000 で割る (ナノ秒からミリ秒へと変換する)
ただし, 以下の場合はここでリターンする.
* 指定された待ち時間が負値の場合
* 指定された待ち時間が絶対時間であり, その時間が現在時刻よりも古い場合
---------------------------------------- -}
// First, demultiplex/decode time arguments
if (time < 0) { // don't wait
return;
}
else if (time == 0 && !isAbsolute) {
time = INFINITE;
}
else if (isAbsolute) {
time -= os::javaTimeMillis(); // convert to relative time
if (time <= 0) // already elapsed
return;
}
else { // relative
time /= 1000000; // Must coarsen from nanos to millis
if (time == 0) // Wait for the minimal time unit if zero
time = 1;
}
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
JavaThread* thread = (JavaThread*)(Thread::current());
assert(thread->is_Java_thread(), "Must be JavaThread");
JavaThread *jt = (JavaThread *)thread;
{- -------------------------------------------
(1) 以下の場合には, ここでリターン.
* 処理対象のスレッドに対して java.lang.Thread.interrupt() が呼ばれていた場合
* 既にシグナルを送られていた場合 (= 待ち時間 0 の WaitForSingleObject() が WAIT_OBJECT_0 を返した場合)
---------------------------------------- -}
// Don't wait if interrupted or already triggered
if (Thread::is_interrupted(thread, false) ||
WaitForSingleObject(_ParkEvent, 0) == WAIT_OBJECT_0) {
ResetEvent(_ParkEvent);
return;
}
{- -------------------------------------------
(1) ThreadBlockInVM 及び OSThreadWaitState で JavaThread/OSThread の状態を変更した後,
WaitForSingleObject() を呼んで誰かが unpark() してくれるまで眠りにつく.
目が覚めたら, ResetEvent() でイベントオブジェクトを非シグナル状態に戻す.
(なお, 寝ている間に java.lang.Thread.suspend() で suspend 状態にされているかもしれないので,
目が覚めた後に JavaThread::handle_special_suspend_equivalent_condition() によるチェックも行っている.
もし suspend されていれば, JavaThread::java_suspend_self() でサスペンドが解除されるまで眠りにつく.)
#TODO JavaThread::set_suspend_equivalent() はどういう意味がある??
---------------------------------------- -}
else {
ThreadBlockInVM tbivm(jt);
OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
jt->set_suspend_equivalent();
WaitForSingleObject(_ParkEvent, time);
ResetEvent(_ParkEvent);
// If externally suspended while waiting, re-suspend
if (jt->handle_special_suspend_equivalent_condition()) {
jt->java_suspend_self();
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.