調用過程
nice()->sys_nice()
函數原型
int nice(int inc);
SYSCALL_DEFINE1(nice, int, increment)
sys_nice()分析
SYSCALL_DEFINE1(nice, int, increment)
{
long nice, retval;
//下面是對參數的校驗 並修正
if (increment < -40)
increment = -40;
if (increment > 40)
increment = 40;
//從此處可以看到nice()的參數是一個增量
nice = TASK_NICE(current) + increment;
//對nice值進行修改 校驗
if (nice < -20)
nice = -20;
if (nice > 19)
nice = 19;
//檢查資源限制
if (increment < 0 && !can_nice(current, nice))
return -EPERM;
//lsm鉤子函數
retval = security_task_setnice(current, nice);
if (retval)
return retval;
//在此處才真正使用nice值設置優先級
set_user_nice(current, nice);
return 0;
}
-------------------------------------------------------------------------------------
void set_user_nice(struct task_struct *p, long nice)
{
int old_prio, delta, on_rq;
unsigned long flags;
struct rq *rq;
//若當前進程的nice等於參數nice nice取值(-20,19)
//或者 nice值小於-20 值不正確
//或者 nice值大於 19 值不正確
if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
return;
/*
* We have to be careful, if called from sys_setpriority(),
* the task might be in the middle of scheduling on another CPU.
*/
rq = task_rq_lock(p, &flags);
update_rq_clock(rq);
//判斷是否爲實時進程 p->policy ==SCHED_FIFO 或者p->policy==SCHED_RR
if (task_has_rt_policy(p))
{
//是實時進程的話 不會影響實時進程的優先級 設置完靜態優先級後 直接返回
p->static_prio = NICE_TO_PRIO(nice);
goto out_unlock;
}
on_rq = p->se.on_rq;//是否在運行隊列
if (on_rq)
dequeue_task(rq, p, 0);//在運行隊列刪除,在重新計算優先級之後,再次插入該runqueue對應的runable task的紅黑樹中
p->static_prio = NICE_TO_PRIO(nice);//通過nice值計算靜態優先級 nice+120
set_load_weight(p);//計算權重 在prio_to_weight數組中以靜態優先級爲下標得到預定的進程權重值
//暫時保存來的動態優先級
old_prio = p->prio;
//調整動態優先級
p->prio = effective_prio(p);
delta = p->prio - old_prio;
if (on_rq) {
enqueue_task(rq, p, 0);//重新插入到運行隊列
/*
* If the task increased its priority or is running and
* lowered its priority, then reschedule its CPU:
*/
//動態優先級變大,
if (delta < 0 || (delta > 0 && task_running(rq, p)))
resched_task(rq->curr);
}
out_unlock:
task_rq_unlock(rq, &flags);
}
-------------------------------------------------------------------------------------
static int effective_prio(struct task_struct *p)
{
p->normal_prio = normal_prio(p);
/*
* If we are RT tasks or we were boosted to RT priority,
* keep the priority unchanged. Otherwise, update priority
* to the normal priority:
*/
//不是實時進程的話 返回 normal_prio 否則優先級不變
//即nice不會改變實時優先級
if (!rt_prio(p->prio))
return p->normal_prio;
return p->prio;
}