石下醉客 发表于 2015-05-26 17:56

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(&current->run_list);
list_add_tail(&current->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个时钟周期?

nswcfd 发表于 2015-05-27 18: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.
               */

nswcfd 发表于 2015-05-27 20:47

#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]
查看完整版本: ULK上关于进程调度scheduler_tick()函数的一段代码