2.2.2 核心概念 - 调度类
简要介绍Sched Class
/* file: kernel/sched/sched.h */
struct sched_class {
#ifdef CONFIG_UCLAMP_TASK
int uclamp_enabled;
#endif
void (*enqueue_task)(struct rq *rq, struct task_struct *p, int flags);
void (*dequeue_task)(struct rq *rq, struct task_struct *p, int flags);
/* 任务主动让出 CPU, 但是其状态依然是 runnable */
void (*yield_task)(struct rq *rq);
bool (*yield_to_task)(struct rq *rq, struct task_struct *p);
/* 检查 p 是否会抢占 rq 中当前正在运行的 task. 通常情况下是在 p 进入 runnable
* 状态时,检查 p 是否会抢占当前正在运行的 task */
void (*check_preempt_curr)(struct rq *rq, struct task_struct *p, int flags);
/* 从 rq 中选择下一个任务来运行 */
struct task_struct *(*pick_next_task)(struct rq *rq);
void (*put_prev_task)(struct rq *rq, struct task_struct *p);
void (*set_next_task)(struct rq *rq, struct task_struct *p, bool first);
#ifdef CONFIG_SMP
/* 检查选中的 cpu 在其 sched_domain
中是否负载是平衡的,如果不平衡则需要对任务进行迁移。
* 并不是所有的 scheduling class 都会实现该方法
* */
int (*balance)(struct rq *rq, struct task_struct *prev, struct rq_flags *rf);
/* 当系统调用 fork, exec 创建一个新的 task 时,在 SMP 系统中需要选择一个合理的
* runqueue 来将该 task 入队。Scheduler 此时需要考虑负载均衡问题 */
int (*select_task_rq)(struct task_struct *p, int task_cpu, int flags);
/* 将任务迁移到目标 CPU 上 */
void (*migrate_task_rq)(struct task_struct *p, int new_cpu);
/* 当任务被唤醒(wake up)之后调用 */
void (*task_woken)(struct rq *this_rq, struct task_struct *task);
/* 修改任务的 CPU 偏好,即其可以被调度到哪些 CPU 上运行 */
void (*set_cpus_allowed)(struct task_struct *p, const struct cpumask *newmask,
u32 flags);
void (*rq_online)(struct rq *rq);
void (*rq_offline)(struct rq *rq);
struct rq *(*find_lock_rq)(struct task_struct *p, struct rq *rq);
#endif
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);
void (*switched_to)(struct rq *this_rq, struct task_struct *task);
void (*prio_changed)(struct rq *this_rq, struct task_struct *task,
int oldprio);
unsigned int (*get_rr_interval)(struct rq *rq, struct task_struct *task);
void (*update_curr)(struct rq *rq);
#define TASK_SET_GROUP 0
#define TASK_MOVE_GROUP 1
#ifdef CONFIG_FAIR_GROUP_SCHED
void (*task_change_group)(struct task_struct *p, int type);
#endif
};Last updated