ULK上关于进程调度scheduler_tick()函数的一段代码
本帖最后由 石下醉客 于 2015-06-03 18:05 编辑更新普通进程的时间片,3,如果进程的时间片没有用完(current->time_slice不等于0),检查当前进程的剩余时间片是否太长:if (TASK_INTERACTIVE(p) && !((task_timeslice(p) -
p->time_slice) % TIMESLICE_GRANULARITY(p)) &&
(p->time_slice >= TIMESLICE_GRANULARITY(p)) &&
(p->array == rq->active)) {
list_del(¤t->run_list);
list_add_tail(¤t->run_list, this_rq()->active->queue+current->prio);
set_tsk_need_resched(p);
}宏TIMESLICE_GRANULARITY产生两个数的乘积给当前进程的bonus,其中一个数为系统中CPU的数量,另一个为比例常量。基本上,具有高静态优先级的交互式进程,其时间片被分成大小为TIMESLICE_GRANULARITY的几个片段,以使这些进程不会独占CPU。
请问使用p而不是current的原因是什么?这段代码具体怎么解释呢?对于普通进程,其bonus的值不超过10,而TIMESLICE_GRANUARITY的值即为bonus,这是不是意味着时间片的值不超过10个时钟周期? 这里有段注释,不知道是否解答了你的问题
/*
* Prevent a too long timeslice allowing a task to monopolize
* the CPU. We do this by splitting up the timeslice into
* smaller pieces.
*
* Note: this does not mean the task's timeslices expire or
* get lost in any way, they just might be preempted by
* another task of equal priority. (one with higher
* priority would have preempted this task already.) We
* requeue this task to the end of the list on this priority
* level, which is in essence a round-robin of tasks with
* equal priority.
*
* This only applies to tasks in the interactive
* delta range with at least TIMESLICE_GRANULARITY to requeue.
*/ #define DEF_TIMESLICE (100 * HZ / 1000)
#define PRIO_BONUS_RATIO 25
#define MAX_BONUS (MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)<--- 10
#define MAX_SLEEP_AVG (DEF_TIMESLICE * MAX_BONUS)
#define CURRENT_BONUS(p) \
(NS_TO_JIFFIES((p)->sleep_avg) * MAX_BONUS / \
MAX_SLEEP_AVG)
#define GRANULARITY (10 * HZ / 1000 ? : 1)<--- 如果HZ=1000则为10
#ifdef CONFIG_SMP
#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \
(1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)) * \
num_online_cpus())
#else
#define TIMESLICE_GRANULARITY(p) (GRANULARITY * \
(1 << (((MAX_BONUS - CURRENT_BONUS(p)) ? : 1) - 1)))
#endif
TIMESLICE_GRANULARITY = GRANULARITY * 1 << (10 - bonus) * #smp,
如果HZ=1000,则GRANULARITY=10;如果忽略smp,则TIMESLICE_GRANULARITY = 10 ~ 5120 (bonus=1~10)。
看起来bonus越大,则TIMESLICE_GRANULARITY越小,最小为10,也就是说,round-robin的越频繁?
if (TASK_INTERACTIVE(p) && !((task_timeslice(p) - <==========仅针对interactive类型的任务
p->time_slice) % TIMESLICE_GRANULARITY(p)) && <==========已经用掉的timeslice是TIMESLICE_GRANULARITY的整数倍(取模余数为零)
(p->time_slice >= TIMESLICE_GRANULARITY(p)) && <==========剩余timeslice不小于TIMESLICE_GRANULARITY
(p->array == rq->active)) { <========== 是当前优先级最高的任务(可能还有其它优先级相同的任务)
requeue_task(p, rq->active); <==========任务重新入队,也就是说实现同等优先级任务的round robin
set_tsk_need_resched(p);
}
页:
[1]