下面准备详细的解释一下scheduler class的各个函数的用途。
struct sched_class {
const struct sched_class *next;
//下一个比其等级低的class。其顺序依次为stop ,deadline,real time,fair,idle。
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 time,fair类型的task。同时由于不同的设计里面这三个class又维护着不同的信息等等。
所以enqueue会根据task的优先级添加到不同的队列中。
void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);
同上,将一个task从runqueue里面删除。
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);
//设置task的affinity
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_interval的hook函数
void (*update_curr) (struct rq *rq);
#ifdef CONFIG_FAIR_GROUP_SCHED
void (*task_move_group) (struct task_struct *p);
//修改cgroup所属组别的钩子函数。
#endif
};