了解 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;
說明:
變更 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;
說明:
二段 kernel code 都呼叫到此 kernel API:
TIP |
|
跟上我們的腳步:請讀以下的文章,再看這篇日記! |
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw