文章目录
- 一、enqueue_task_rt 函数 ( 插入进程到执行队列 )
- 二、pick_next_task_rt 函数 ( 从执行队列中选择优先级最高的进程 )
本篇博客中 , 开始分析 struct sched_class rt_sched_class
结构体变量 中的各个 函数指针 指向的 函数源码 ;
rt_sched_class
结构体 在 Linux 内核源码的 linux-5.6.18kernelschedrt.c
源文件中定义 , 实时调度 相关的 核心函数 也定义在该源码中 ;
一、enqueue_task_rt 函数 ( 插入进程到执行队列 )
enqueue_task_rt
函数用于 更新 " 调度信息 " , 将 " 实时调度实体 " sched_rt_entity
插入到 " 执行队列 " ( 红黑树 ) 的 末尾 ( 红黑树最右侧 ) ;
该函数的核心代码是 调用 enqueue_pushable_task
函数 , 将 当前的 " 实时调度实体 " 插入到 对应的优先级列表 中 ;
/*
* Adding/removing a task to/from a priority array:
*/
static void
enqueue_task_rt(struct rq *rq, struct task_struct *p, int flags)
{
struct sched_rt_entity *rt_se = &p->rt;
if (flags & ENQUEUE_WAKEUP)
rt_se->timeout = 0;
enqueue_rt_entity(rt_se, flags);
if (!task_current(rq, p) && p->nr_cpus_allowed > 1)
enqueue_pushable_task(rq, p);
}
源码路径 : linux-5.6.18kernelschedrt.c#1367
二、pick_next_task_rt 函数 ( 从执行队列中选择优先级最高的进程 )
enqueue_task_rt
函数用于 在 " 执行队列 " ( 红黑树 ) 中 , 选择 " 优先级最高 " 的 " 实时进程 " , 用于执行 ;
该函数的核心代码是 调用 _pick_next_task_rt
函数 ;
static struct task_struct *pick_next_task_rt(struct rq *rq)
{
struct task_struct *p;
if (!sched_rt_runnable(rq))
return NULL;
p = _pick_next_task_rt(rq);
set_next_task_rt(rq, p, true);
return p;
}
源码路径 : linux-5.6.18kernelschedrt.c#1616
在 _pick_next_task_rt
函数 中 , 又调用了 pick_next_rt_entity
函数 ;
static struct task_struct *_pick_next_task_rt(struct rq *rq)
{
struct sched_rt_entity *rt_se;
struct rt_rq *rt_rq = &rq->rt;
do {
rt_se = pick_next_rt_entity(rq, rt_rq);
BUG_ON(!rt_se);
rt_rq = group_rt_rq(rt_se);
} while (rt_rq);
return rt_task_of(rt_se);
}
源码路径 : linux-5.6.18kernelschedrt.c#1602
pick_next_rt_entity
函数 源码如下 :
idx = sched_find_first_bit(array->bitmap);
作用是 找到 可用的实体 ;
queue = array->queue idx;
作用是 从 " 链表组 " 找到对应的链表 ;
return next
返回找到的 实时运行实体 ;
static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq,
struct rt_rq *rt_rq)
{
struct rt_prio_array *array = &rt_rq->active;
struct sched_rt_entity *next = NULL;
struct list_head *queue;
int idx;
idx = sched_find_first_bit(array->bitmap);
BUG_ON(idx >= MAX_RT_PRIO);
queue = array->queue idx;
next = list_entry(queue->next, struct sched_rt_entity, run_list);
return next;
}
源码路径 : linux-5.6.18kernelschedrt.c#1585