hotspot/src/share/vm/runtime/thread.cpp
// Part II of external suspension.
// A JavaThread self suspends when it detects a pending external suspend
// request. This is usually on transitions. It is also done in places
// where continuing to the next transition would surprise the caller,
// e.g., monitor entry.
//
// Returns the number of times that the thread self-suspended.
//
// Note: DO NOT call java_suspend_self() when you just want to block current
// thread. java_suspend_self() is the second stage of cooperative
// suspension for external suspend requests and should only be used
// to complete an external suspend request.
//
int JavaThread::java_suspend_self() {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
int ret = 0;
{- -------------------------------------------
(1) もしこのスレッドが既に終了処理に入っている(or 終了している)なら,
待機してもしょうが無いので, ここでリターン.
---------------------------------------- -}
// we are in the process of exiting so don't suspend
if (is_exiting()) {
clear_external_suspend();
return ret;
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(_anchor.walkable() ||
(is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()),
"must have walkable stack");
{- -------------------------------------------
(1)
---------------------------------------- -}
MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag);
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(!this->is_ext_suspended(),
"a thread trying to self-suspend should not already be suspended");
{- -------------------------------------------
(1)
---------------------------------------- -}
if (this->is_suspend_equivalent()) {
// If we are self-suspending as a result of the lifting of a
// suspend equivalent condition, then the suspend_equivalent
// flag is not cleared until we set the ext_suspended flag so
// that wait_for_ext_suspend_completion() returns consistent
// results.
this->clear_suspend_equivalent();
}
{- -------------------------------------------
(1) resume 処理によって suspend 状態が解除されるまで,
SR_lock に対して Monitor::wait() を呼ぶことで待機する.
(See: [here](no2114zBI.html) for details)
---------------------------------------- -}
// A racing resume may have cancelled us before we grabbed SR_lock
// above. Or another external suspend request could be waiting for us
// by the time we return from SR_lock()->wait(). The thread
// that requested the suspension may already be trying to walk our
// stack and if we return now, we can change the stack out from under
// it. This would be a "bad thing (TM)" and cause the stack walker
// to crash. We stay self-suspended until there are no more pending
// external suspend requests.
while (is_external_suspend()) {
ret++;
this->set_ext_suspended();
// _ext_suspended flag is cleared by java_resume()
while (is_ext_suspended()) {
this->SR_lock()->wait(Mutex::_no_safepoint_check_flag);
}
}
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return ret;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.