hotspot/src/os/solaris/vm/os_solaris.cpp
// set_lwp_priority
//
// Set the priority of the lwp. This call should only be made
// when using bound threads (T2 threads are bound by default).
//
int set_lwp_priority (int ThreadID, int lwpid, int newPrio )
{
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
int rslt;
int Actual, Expected, prv;
pcparms_t ParmInfo; // for GET-SET
#ifdef ASSERT
pcparms_t ReadBack; // for readback
#endif
{- -------------------------------------------
(1)
---------------------------------------- -}
// Set priority via PC_GETPARMS, update, PC_SETPARMS
// Query current values.
// TODO: accelerate this by eliminating the PC_GETPARMS call.
// Cache "pcparms_t" in global ParmCache.
// TODO: elide set-to-same-value
{- -------------------------------------------
(1) もし初期化時に失敗していたら (= priocntl_enable 変数の値が false であれば), ここでリターン.
(See: lwp_priocntl_init())
(ついでに(トレース出力)も出している)
---------------------------------------- -}
// If something went wrong on init, don't change priorities.
if ( !priocntl_enable ) {
if (ThreadPriorityVerbose)
tty->print_cr("Trying to set priority but init failed, ignoring");
return EINVAL;
}
{- -------------------------------------------
(1) 引数で指定された lwp id が不正な場合, ここでリターン.
(ついでに(トレース出力)も出している)
---------------------------------------- -}
// If lwp hasn't started yet, just return
// the _start routine will call us again.
if ( lwpid <= 0 ) {
if (ThreadPriorityVerbose) {
tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set",
ThreadID, newPrio);
}
return 0;
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (ThreadPriorityVerbose) {
tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
ThreadID, lwpid, newPrio);
}
{- -------------------------------------------
(1) (priocntl_ptr 変数経由で) priocntl() を呼び出して, 優先度情報(pcparms_t型のデータ)を取得する.
失敗したらここでリターン.
---------------------------------------- -}
memset(&ParmInfo, 0, sizeof(pcparms_t));
ParmInfo.pc_cid = PC_CLNULL;
rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
if (rslt < 0) return errno;
{- -------------------------------------------
(1) 取得した優先度情報を変更して, 新しい優先度に対応する優先度情報(pcparms_t型のデータ)を作成.
---------------------------------------- -}
if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms;
rtInfo->rt_pri = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio);
rtInfo->rt_tqsecs = RT_NOCHANGE;
rtInfo->rt_tqnsecs = RT_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
}
} else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
int maxClamped = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
iaInfo->ia_upri = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
iaInfo->ia_uprilim = IA_NOCHANGE;
iaInfo->ia_mode = IA_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr ("IA: [%d...%d] %d->%d\n",
iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
}
} else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
int maxClamped = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim);
prv = tsInfo->ts_upri;
tsInfo->ts_upri = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio);
tsInfo->ts_uprilim = IA_NOCHANGE;
if (ThreadPriorityVerbose) {
tty->print_cr ("TS: %d [%d...%d] %d->%d\n",
prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
}
if (prv == tsInfo->ts_upri) return 0;
} else {
if ( ThreadPriorityVerbose ) {
tty->print_cr ("Unknown scheduling class\n");
}
return EINVAL; // no clue, punt
}
{- -------------------------------------------
(1) (priocntl_ptr 変数経由で) priocntl() を呼び出して, 優先度を変更する.
失敗したらここでリターン.
---------------------------------------- -}
rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
if (ThreadPriorityVerbose && rslt) {
tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
}
if (rslt < 0) return errno;
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef ASSERT 時にのみ実行)
---------------------------------------- -}
#ifdef ASSERT
// Sanity check: read back what we just attempted to set.
// In theory it could have changed in the interim ...
//
// The priocntl system call is tricky.
// Sometimes it'll validate the priority value argument and
// return EINVAL if unhappy. At other times it fails silently.
// Readbacks are prudent.
if (!ReadBackValidate) return 0;
memset(&ReadBack, 0, sizeof(pcparms_t));
ReadBack.pc_cid = PC_CLNULL;
rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
assert(rslt >= 0, "priocntl failed");
Actual = Expected = 0xBAD;
assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
Actual = RTPRI(ReadBack)->rt_pri;
Expected = RTPRI(ParmInfo)->rt_pri;
} else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
Actual = IAPRI(ReadBack)->ia_upri;
Expected = IAPRI(ParmInfo)->ia_upri;
} else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
Actual = TSPRI(ReadBack)->ts_upri;
Expected = TSPRI(ParmInfo)->ts_upri;
} else {
if ( ThreadPriorityVerbose ) {
tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid);
}
}
if (Actual != Expected) {
if ( ThreadPriorityVerbose ) {
tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
}
}
#endif
{- -------------------------------------------
(1) リターン
---------------------------------------- -}
return 0;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.