1. task_struct
说到调度,第一个首先相当的应该是task_struct,它用于表示一个进程/线程,它可以看做调度的一个实体单位,该结构体中,几个与调度较为密切的成员如下:
struct task_struct {
int prio, static_prio, normal_prio;
unsigned int rt_priority;
const struct sched_class *sched_class;
struct sched_entity se;
struct sched_rt_entity rt;
#ifdef CONFIG_CGROUP_SCHED
struct task_group *sched_task_group;
#endif
struct sched_dl_entity dl;
...
unsigned int policy;
int nr_cpus_allowed;
cpumask_t cpus_allowed;
}
- rt_priority是实时进程的优先级,其值范围为0到99,值越大优先级越高;
- prio和normal_prio表示动态优先级,static_prio是静态优先级,静态优先级由启动时静态分配,例如使用nice值或sched_setscheduler()系统调用。normal_prio基于静态优先级及调度策略计算,prio用于某些情况下内核需要暂时提高进程的优先级。
- sched_class是调度器类;
2. sched_class
3. sched_entity
struct sched_entity {
struct load_weight load;
struct rb_node run_node;
unsigned int on_rq;
u64 exec_start;
u64 sum_exec_runtime;
u64 vruntime;
u64 prev_sum_exec_runtime;
}
- load用于负载均衡,指定了权重,计算该值是调度器的一项重任;
- run_node是一颗红黑树节点,使得实体可在红黑树上排序;
- on_rq指示该实体是否在就绪队列中:struct rq;在就绪队列中表示等待调度;
- exec_start以及接下来的几个变量用于时间统计,主要是记录CPU消耗时间用于CFS调度器。sum_exec_runtime跟踪进程运行时在CPU上执行的总时间,exec_start指示当前执行的开始,例如新进程加入就绪队列或周期性调度器中,每次调用会计算当前时间与exec_start差值叠加到sum_exec_runtime中,而当前时间则设为exec_start,prev_sum_exec_runtime用于计算上次进程执行的CPU时间,vruntime记录进程在执行期间虚拟时钟上流逝的时间数量。