调用过程
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;
}