2014年9月14日 星期日

pick_next_task()


source:pick_next_task



2659 pick_next_task(struct rq *rq, struct task_struct *prev)
2660 {
2661         const struct sched_class *class = &fair_sched_class;
2662         struct task_struct *p;
2664         /*
2665          * Optimization: we know that if all tasks are in
2666          * the fair class we can call that function directly:
2667          */
            /*檢查目前總Runnable Task數量是否跟放在Fair Class中的數量一致,如果相同,就執行執行Fair Scheduling Class的pick_next_task抓取下一個執行的Task*/
2668         if (likely(prev->sched_class == class &&
2669                    rq->nr_running == rq->cfs.h_nr_running)) {
2670                 p = fair_sched_class.pick_next_task(rq, prev);
/*pick_next_task_fair函数首先调用pick_next_entity,在pick_next_entity中首先run queue中(用红黑樹管理)選出vruntime時間最小的個个task,然後再和cfs_rq->next,cfs_rq->last兩個task做比較。這裡給予cfs_rq->next,和cfs_rq->last兩個task優先調度機會,只要next或者last兩個process vruntime的时间没有比最小的vruntime大出调度的颗粒度时间,就会优先选择next或者last__clear_buddies函数中会将cfs_rq->next和cfs_rq->last两个指针设置成为NULL
set_next_entity将选择的下一个运行的进程设置到curr指针。*/
2671                 if (unlikely(p == RETRY_TASK))
2672                         goto again;
2674                 /* 當fair_sched_class->next == idle_sched_class,還是繼續執行,因為cfs的priority較高 */
2675                 if (unlikely(!p))
2676                         p = idle_sched_class.pick_next_task(rq, prev);
2678                 return p;
2679         }
2681 again:
2682         for_each_class(class) {
2683                 p = class->pick_next_task(rq, prev);
2684                 if (p) {
2685                         if (unlikely(p == RETRY_TASK))/*May return RETRY_TASK when it finds a higher prio class has runnable tasks.*/
2686                                 goto again;
2687                         return p;
2688                 }
2689         }
2691         BUG(); /* the idle class will always have a runnable task */
2692 }

沒有留言:

張貼留言