系統調用nice()的內核之路

調用過程

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章