了解 sys_getpriority() 後,要看懂 sys_setpriority() 就不是問題了。
| 97 | sys_setpriority | linux/kernel/sys.c |
| 類別:Systems 原型宣告:long sys_setpriority(int which, int who, int niceval); 用途說明:變更 process 的排程優先序(Priority)。 |
||
Kernel (2.6.11 or above) 實作:
asmlinkage long sys_setpriority(int which, int who, int niceval)
{
struct task_struct *g, *p;
struct user_struct *user;
int error = -EINVAL;
if (which > 2 || which < 0)
goto out;
/* normalize: avoid signed division (rounding problems) */
error = -ESRCH;
if (niceval < -20)
niceval = -20;
if (niceval > 19)
niceval = 19;
read_lock(&tasklist_lock);
switch (which) {
case PRIO_PROCESS:
if (!who)
who = current->pid;
p = find_task_by_pid(who);
if (p)
error = set_one_prio(p, niceval, error);
break;
case PRIO_PGRP:
if (!who)
who = process_group(current);
do_each_task_pid(who, PIDTYPE_PGID, p) {
error = set_one_prio(p, niceval, error);
} 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)
error = set_one_prio(p, niceval, error);
while_each_thread(g, p);
if (who != current->uid)
free_uid(user); /* For find_user() */
break;
}
out_unlock:
read_unlock(&tasklist_lock);
out:
return error;
}
|
||
Jollen 的說明
程式一開始先判斷 which 參數的正確性,並且將 user process 所指定的 nice 值限定在 [-20..19] 的範圍內:
if (which > 2 || which < 0) goto out; /* normalize: avoid signed division (rounding problems) */ error = -ESRCH; if (niceval < -20) niceval = -20; if (niceval > 19) niceval = 19;
底下我們來討論 PRIO_PROCESS 與 PRIO_PGRP 參數的實作,強烈建議您先行閱讀本文最後所整理的文章,再回頭來看以下的說明,才能得到最佳學習效果。
變更 priority:PRIO_PROCESS
主要的程式片斷如下:
case PRIO_PROCESS: /* 請看 1. */ if (!who) who = current->pid; /* 請看 1. */ p = find_task_by_pid(who); /* 請看 2. */ if (p) /* 請看 3. */ error = set_one_prio(p, niceval, error); /* 請看 3. */ break;
說明:
- 若 which = PRIO_PROCESS,則 who 的值就是 process ID。因為 who 不能為 0,所以如果 who 是 0 的話,就指定為 current 的 PID。
- find_task_by_pid() 是 kernel API,用來取得 PID 的 process descriptor。我們已經學過了!
- 如果 p 不是 NULL,就呼叫 set_one_prio(),修改 p 的「nice 值」為 niceval。
變更 priority:PRIO_PGRP
主要的程式片斷如下:
case PRIO_PGRP:
if (!who)
who = process_group(current);
do_each_task_pid(who, PIDTYPE_PGID, p) { /* 請看 1. */
error = set_one_prio(p, niceval, error); /* 請看 1. */
} while_each_task_pid(who, PIDTYPE_PGID, p); /* 請看 1. */
break;
說明:
- 在迴圈裡,逐一修改 process group 裡的 process,將其優先序變更為 niceval。這樣的迴圈,在 sys_getpriority() 也看過一次!
二段 kernel code 都呼叫到此 kernel API:
- kernel API - set_one_prio():傳入 process descriptor 與新的 nice 值,將 process 的 priorioty 做變更。
| TIP |
|
| 跟上我們的腳步:請讀以下的文章,再看這篇日記! |
--jollen
