hotspot/src/os/solaris/vm/os_solaris.cpp
// Thread start routine for all new Java threads
extern "C" void* java_start(void* thread_addr) {
{- -------------------------------------------
(1) alloca() を呼んで, スタックの位置を多少増減させておく.
(増減させる量は, 自分自身の process id と
static な int 変数(以下の counter)に基づいて決めている)
(なおコメントによると, これはキャッシュ上での競合を減らすための措置.
他のスレッドのスタックとキャッシュラインがかぶっていると, お互いに invalidate しあうことになるので.
競合は同じ HotSpot プロセス内のスレッド同士でも起こりうるし,
別の HotSpot プロセス内のスレッドとも起こりうる.
特に, Hyperthreading 環境ではずらすことによる効果が大きい, とのこと.)
---------------------------------------- -}
// Try to randomize the cache line index of hot stack frames.
// This helps when threads of the same stack traces evict each other's
// cache lines. The threads can be either from the same JVM instance, or
// from different JVM instances. The benefit is especially true for
// processors with hyperthreading technology.
static int counter = 0;
int pid = os::current_process_id();
alloca(((pid ^ counter++) & 7) * 128);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
int prio;
Thread* thread = (Thread*)thread_addr;
OSThread* osthr = thread->osthread();
{- -------------------------------------------
(1) _lwp_self() でカレントスレッドに対応する LWP ID を取得し, lwp_id フィールドに記録しておく.
---------------------------------------- -}
osthr->set_lwp_id( _lwp_self() ); // Store lwp in case we are bound
{- -------------------------------------------
(1) フィールドの初期化
(取得した schedctl_t は何に使われる?? 現在の実装ではどこからも使われていないような... #TODO)
---------------------------------------- -}
thread->_schedctl = (void *) schedctl_init () ;
{- -------------------------------------------
(1) UseNUMA オプションが指定されている場合は,
os::numa_get_group_id() で id を取得し,
カレントスレッドの lgrp_id フィールドにセットしておく.
(See: [here](no28916ddy.html) for details)
---------------------------------------- -}
if (UseNUMA) {
int lgrp_id = os::numa_get_group_id();
if (lgrp_id != -1) {
thread->set_lgrp_id(lgrp_id);
}
}
{- -------------------------------------------
(1) 処理対象の OSThread が対応する thread_t を持っており
(<= 持っていないのはどういうケース?? メインスレッド?? JNI スレッド?? #TODO)
かつ UseThreadPriorities オプションが指定されている場合には,
thr_setprio() でスレッドの優先度が設定されていたはず (See: os::create_thread()).
ただし, その段階では LWP との対応が決まっていなかったので,
改めて os::set_native_priority() を呼び出して LWP レベルでも優先度を設定しておく.
---------------------------------------- -}
// If the creator called set priority before we started,
// we need to call set priority now that we have an lwp.
// Get the priority from libthread and set the priority
// for the new Solaris lwp.
if ( osthr->thread_id() != -1 ) {
if ( UseThreadPriorities ) {
thr_getprio(osthr->thread_id(), &prio);
if (ThreadPriorityVerbose) {
tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n",
osthr->thread_id(), osthr->lwp_id(), prio );
}
os::set_native_priority(thread, prio);
}
} else if (ThreadPriorityVerbose) {
warning("Can't set priority in _start routine, thread id hasn't been set\n");
}
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
{- -------------------------------------------
(1) os::Solaris::hotspot_sigmask() を呼び出して, 適切なシグナルマスクを設定しておく.
---------------------------------------- -}
// initialize signal mask for this thread
os::Solaris::hotspot_sigmask(thread);
{- -------------------------------------------
(1) Thread::run() (もしくはサブクラスでオーバーライドされたメソッド) を呼び出して,
スレッドのメイン処理を実行する.
---------------------------------------- -}
thread->run();
{- -------------------------------------------
(1) os::Solaris::_os_thread_count フィールドの値を減少させておく.
(この値は, os::create_thread() 内でのランタイムチェックや調整処理に使われている.
See: os::create_thread())
ただし, 処理対象のスレッドが VM Thread の場合は, この処理は行わない.
(コメントによると,
ここの処理では Atomic::dec を使用するが, VM Thread の場合は
メインスレッドが Atomic::dec のコードを含んでいる CodeHeap を開放済みかもしれない,
とのこと.)
また, VMThread::vm_thread() が NULL の場合もこの処理を行わないようだが,
これは VM Thread が死んだ後にここに到達したスレッドがいた場合?? #TODO
(ネイティブコードを実行していたスレッドが VM Thread 死亡後に到達するケース??)
---------------------------------------- -}
// One less thread is executing
// When the VMThread gets here, the main thread may have already exited
// which frees the CodeHeap containing the Atomic::dec code
if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
Atomic::dec(&os::Solaris::_os_thread_count);
}
{- -------------------------------------------
(1) UseDetachedThreads オプションが指定されている場合は,
ここで thr_exit() システムコールを呼んでスレッドを終了させる.
(この場合, スレッド自体が無くなるので, ここで実行は終了)
---------------------------------------- -}
if (UseDetachedThreads) {
thr_exit(NULL);
ShouldNotReachHere();
}
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return NULL;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.