sched_post_fork 源码
时间: 2023-11-30 14:02:06 浏览: 129
下面是 `sched_post_fork` 函数的部分源码,代码摘自 Linux 内核版本 5.15.5:
```c
void sched_post_fork(struct task_struct *p)
{
struct rq_flags rf;
struct sched_entity *se = &p->se;
struct task_struct *parent = p->parent;
struct sched_entity *parent_se = &parent->se;
if (parent_se->on_rq && !se->on_rq) {
/*
* parent is on a runqueue, but we just forked the child and it's
* not on any runqueue yet. This means we need to do a few things
* to get the child properly accounted for.
*/
p->se.load.weight = 0;
se->vruntime = parent_se->vruntime;
se->sum_exec_runtime = parent_se->sum_exec_runtime;
se->prev_sum_exec_runtime = parent_se->prev_sum_exec_runtime;
se->avg_overlap = parent_se->avg_overlap;
/*
* We need to add the child to the runqueue. This is tricky, as
* we cannot just add it to the parent's runqueue, as that would
* mess up the order of the tasks. Instead, we need to add it
* to the right runqueue based on its priority.
*/
raw_spin_lock_irqsave(&rq_lock(p), rf);
enqueue_task_rq(p, task_cpu(p), ENQUEUE_WAKEUP);
raw_spin_unlock_irqrestore(&rq_lock(p), rf);
}
/*
* We need to reset the child's CPU time and other accounting
* information, as it is starting fresh.
*/
schedstat_set(p->se.statistics.wait_start, 0);
cpuacct_clear_stats(p);
memset(&p->sched_info, 0, sizeof(p->sched_info));
}
```
该函数主要做了以下几件事情:
1. 复制父进程的调度实体信息,包括进程的优先级、调度策略、调度参数等;
2. 为子进程创建新的调度实体,并将其加入到任务队列中;
3. 重置子进程的 CPU 时间和其他计算信息,以确保子进程可以从头开始执行。
需要注意的是,`sched_post_fork` 函数只是为子进程更新调度信息和创建调度实体,并将其加入到任务队列中。具体的调度过程和调度策略等信息,是由 CFS 调度器来进行实现和维护的。因此,在理解 `sched_post_fork` 函数的实现时,需要结合 CFS 调度器的内部实现和调度策略等信息进行理解。
阅读全文