下面准备详细的解释一下scheduler class的各个函数的用途。

struct sched_class {

        const struct sched_class *next;

//下一个比其等级低的class。其顺序依次为stop deadlinereal timefairidle

         void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);

//将一个task插入到相应的runqueue里面。

Struct rq {

        struct cfs_rq cfs;

        struct rt_rq rt;

        struct dl_rq dl;

};

Struct rq是一个比较大的结构体,per cpu的。但是由于存在很多不同种类的task,所以rq里面分别有三个队列用于维护 deadline real timefair类型的task。同时由于不同的设计里面这三个class又维护着不同的信息等等。

所以enqueue会根据task的优先级添加到不同的队列中。

        void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);

同上,将一个taskrunqueue里面删除。

        void (*yield_task) (struct rq *rq);

//当前task放弃CPU的钩子函数

        bool (*yield_to_task) (struct rq *rq, struct task_struct *p, boolpreempt);

//yield to task

        void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, intflags);

//检查当前task是否需要被抢占

        /*  

         * It is the responsibility of the pick_next_task() method that will

         * return the next task to call put_prev_task() on the @prev task or

         * something equivalent.

         *

         * May return RETRY_TASK when it finds a higher prio class has runnable

         * tasks.

         */

        struct task_struct * (*pick_next_task) (struct rq *rq,

                                                struct task_struct *prev);

//用于从rq中选择下一个运行的task

        void (*put_prev_task) (struct rq *rq, struct task_struct *p);

//task p重新放入到rq中去。

 

#ifdef CONFIG_SMP

        int  (*select_task_rq)(structtask_struct *p, int task_cpu, int sd_flag, int flags);

//为被唤醒的task或者刚创建的task 选择运行队列。

        void (*migrate_task_rq)(struct task_struct *p);

//task migrate的钩子函数

 

        void (*task_waking) (struct task_struct *task);

        void (*task_woken) (struct rq *this_rq, struct task_struct *task);

//唤醒task的钩子函数

        void (*set_cpus_allowed)(struct task_struct *p,

                                 const structcpumask *newmask);

//设置taskaffinity

 

        void (*rq_online)(struct rq *rq);

        void (*rq_offline)(struct rq *rq);

#endif

 

        void (*set_curr_task) (struct rq *rq);

        void (*task_tick) (struct rq *rq, struct task_struct *p, int queued);

        void (*task_fork) (struct task_struct *p);

        void (*task_dead) (struct task_struct *p);

        /*

         * The switched_from() call is allowed to drop rq->lock, therefore we

         * cannot assume the switched_from/switched_to pair is serliazed by

         * rq->lock. They are however serialized by p->pi_lock.

         */

        void (*switched_from) (struct rq *this_rq, struct task_struct *task);

//用于修改priority或者修改scheduler class时的hook函数。用于从之前的class中退出。

        void (*switched_to) (struct rq *this_rq, struct task_struct *task);

//用于修改priority或者修改scheduler class时的hook函数,用于进入新的class中。

        void (*prio_changed) (struct rq *this_rq, struct task_struct *task,

                             int oldprio);

//修改优先级,不涉及修改scheduler class

        unsigned int (*get_rr_interval) (struct rq *rq,

                                         structtask_struct *task);

//系统调用sched_rr_get_intervalhook函数

        void (*update_curr) (struct rq *rq);

 

#ifdef CONFIG_FAIR_GROUP_SCHED

        void (*task_move_group) (struct task_struct *p);

//修改cgroup所属组别的钩子函数。

#endif

};

12-11 00:40