nice() 是用來變更 process 優先序(priority)的 system call 也是最古老的一個,sys_getpriority() 與 sys_setpriority() 則是取代 sys_nice() 的新實作,今天我們先討論一下 'sys_getpriority'。
| 96 | sys_getpriority | linux/kernel/sys.c |
| 類別:Systems 原型宣告:long sys_getpriority(int which, int who); 用途說明:取得 process 的排程優先序(Priority)。 |
||
Kernel (2.6.11 or above) 實作:
/*
* Ugh. To avoid negative return values, "getpriority()" will
* not return the normal nice-value, but a negated value that
* has been offset by 20 (ie it returns 40..1 instead of -20..19)
* to stay compatible.
*/
asmlinkage long sys_getpriority(int which, int who)
{
struct task_struct *g, *p;
struct user_struct *user;
long niceval, retval = -ESRCH;
if (which > 2 || which < 0)
return -EINVAL;
read_lock(&tasklist_lock);
switch (which) {
case PRIO_PROCESS:
if (!who)
who = current->pid;
p = find_task_by_pid(who);
if (p) {
niceval = 20 - task_nice(p);
if (niceval > retval)
retval = niceval;
}
break;
case PRIO_PGRP:
if (!who)
who = process_group(current);
do_each_task_pid(who, PIDTYPE_PGID, p) {
niceval = 20 - task_nice(p);
if (niceval > retval)
retval = niceval;
} while_each_task_pid(who, PIDTYPE_PGID, p);
break;
case PRIO_USER:
user = current->user;
if (!who)
who = current->uid;
else
if ((who != current->uid) && !(user = find_user(who)))
goto out_unlock; /* No processes for this user */
do_each_thread(g, p)
if (p->uid == who) {
niceval = 20 - task_nice(p);
if (niceval > retval)
retval = niceval;
}
while_each_thread(g, p);
if (who != current->uid)
free_uid(user); /* for find_user() */
break;
}
out_unlock:
read_unlock(&tasklist_lock);
return retval;
}
|
||
Jollen 的說明
讓我們來看一下 system call service - 'sys_getpriority' 的程式實作。首先是 sys_getpriority() 的參數:which 與 who,這二個參數對應到 getpriority() 的 which 與 who 參數;如果您不是很清楚 which/who 的話,請參閱前幾天的日記。
我們拿底下的程式片斷來討論:
switch (which) { /* 請看 1. */
case PRIO_PROCESS: /* 請看 2. */
if (!who) /* 請看 2. */
who = current->pid;
p = find_task_by_pid(who); /* 請看 3. */
if (p) { /* 請看 4. */
niceval = 20 - task_nice(p); /* 請看 5. */
if (niceval > retval)
retval = niceval;
}
break;
...
}
說明如下:
- 判斷 which 參數,假設我們想要取得 process 的 priority,那麼 which 的值就是 PRIO_PROCESS。
- 若 which = PRIO_PROCESS,則 who 的值就是 process ID。因為 who 不應該為 0,所以如果 who 是 0 的話,就指定為 current 的 PID。
- find_task_by_pid() 是 kernel API,用來取得 PID 的 process descriptor。
- 如果 p 不是 NULL,就呼叫 task_nice(),取得 process 的「nice 值」,然後傳回 nice 值。
- kernel 的 nice 值範圍為 [-20..19],但 user-space 的 nice 值是 [40,1],所以要做換算:[20-(-20)..20-19] = [40..1]。
喔!要取得 process priority 的 kernel 實作看起來還挺簡單的。我們又學到了:
- kernel API - find_task_by_pid():傳入 PID,取得該 process 的 process descriptor。
- kernel API - task_nice():傳入 process descriptor,取得該 process 的 priority(nice 值)。
| TIP |
|
| 跟上我們的腳步:請讀以下的文章,再看這篇日記! |
--jollen
