linux组调度思想浅析

  • A+
所属分类:Linux系统

上次我们讲到了主调度器。然后提及了下组调度。

今天我们来看下组调度。

static struct task_struct *pick_next_task_fair(struct rq *rq)
{
	struct task_struct *p;
	struct cfs_rq *cfs_rq = &rq->cfs;
	struct sched_entity *se;

	if (!cfs_rq->nr_running)
		return NULL;

	do {
		se = pick_next_entity(cfs_rq);
		set_next_entity(cfs_rq, se);
		cfs_rq = group_cfs_rq(se);
	} while (cfs_rq);

	p = task_of(se);
	if (hrtick_enabled(rq))
		hrtick_start_fair(rq, p);

	return p;
}

 

代码很简单,其实在2.4以前是没有组调度的。就不会有group_cfs_rq这个队列,那么所有task都在全局的rq->cfs,就是刚开始的。

后面为了引入分组的概念,就有了组调度。

引入分组的概念后,原来对task直接进行的操作就变得不那么遍历,就引入了sched_entity。整体结构如下。

linux组调度思想浅析

 

结合代码理解下

  • 首先代码 struct cfs_rq *cfs_rq = &rq->cfs; 拿到全局的cfs_rq。
  • 然后进行一次pick 拿到sched_entity se(假设是A cfs_rq) -----------sched_entity 和 task_group是可以相互转换的
  • 然后把全局的cfs_rq 复制成现在的cfs_rq(假设是A cfs_rq)
  • 然后是while循环,如果A下面没有节点了,就结束循环,但是A下面还有节点,就循环,再重新赋值,如此如此。知道根部。
  • 那么假设我们在A的下面 task_gruop1 停止了,因为它的cfs_rq是空的。
  • 接下来就把task_group1 转换成task_struck p。
  • 最后就结束返回。

同理rt队列也是这样的:如果主调度器(),选择的是rt_sched_class 那就 pick_next_task_rt

那么就会从task_group A 的rt_rq开始调度

task_group不仅仅有cfs_rq 还有 rt_rq。

关于task_group 和组调度的详细我们接下来会详细分析。

 

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: