hotspot/src/os/linux/vm/os_linux.cpp
//
// Handler function invoked when a thread's execution is suspended or
// resumed. We have to be careful that only async-safe functions are
// called here (Note: most pthread functions are not async safe and
// should be avoided.)
//
// Note: sigwait() is a more natural fit than sigsuspend() from an
// interface point of view, but sigwait() prevents the signal hander
// from being run. libpthread would get very confused by not having
// its signal handlers run and prevents sigwait()'s use with the
// mutex granting granting signal.
//
// Currently only ever called on the VMThread
//
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// Save and restore errno to avoid confusing native code with EINTR
// after sigsuspend.
int old_errno = errno;
Thread* thread = Thread::current();
OSThread* osthread = thread->osthread();
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(thread->is_VM_thread(), "Must be VMThread");
{- -------------------------------------------
(1) 以下の処理は, サスペンドされた場合.
サスペンドされた場合 (= sr フィールドが SR_SUSPEND の場合) は,
os::Linux::SuspendResume::set_suspended() を呼んで sr フィールドの SR_SUSPENDED ビットを立てた後,
sigsuspend() を呼んで眠りにつく.
(sr フィールドが SR_CONTINUE に変更されてから SR_signum が再度送信されるまで, ここで待機)
(なお, 眠りから覚めたら resume_clear_context() を呼んで sr フィールドをリセットしている)
---------------------------------------- -}
// read current suspend action
int action = osthread->sr.suspend_action();
if (action == SR_SUSPEND) {
suspend_save_context(osthread, siginfo, context);
// Notify the suspend action is about to be completed. do_suspend()
// waits until SR_SUSPENDED is set and then returns. We will wait
// here for a resume signal and that completes the suspend-other
// action. do_suspend/do_resume is always called as a pair from
// the same thread - so there are no races
// notify the caller
osthread->sr.set_suspended();
sigset_t suspend_set; // signals for sigsuspend()
// get current set of blocked signals and unblock resume signal
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
sigdelset(&suspend_set, SR_signum);
// wait here until we are resumed
do {
sigsuspend(&suspend_set);
// ignore all returns until we get a resume signal
} while (osthread->sr.suspend_action() != SR_CONTINUE);
resume_clear_context(osthread);
{- -------------------------------------------
(1) 以下の処理は, レジュームされた場合.
---------------------------------------- -}
} else {
assert(action == SR_CONTINUE, "unexpected sr action");
// nothing special to do - just leave the handler
}
{- -------------------------------------------
(1)
---------------------------------------- -}
errno = old_errno;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.