时钟中断到设置调度标记位

   这次主要从时钟tick中断响应到设置进程的调度标志位过程的分析。内核版本4.1.15。

在这里插入图片描述
时钟的中断函数响应后最终会调用scheduler_tick函数,scheduler_tick函数函数中有句话curr->sched_class->task_tick(rq, curr, 0); 这个钩子函数的注册在kernel/sched/fair.c中。task_tick_fair最终调用的是check_preempt_tick函数。这个函数的作用就是从二叉树中找出最需要执行的进程,然后把该进程的调度标志置位。__pick_first_entity就是找到最需要执行的进程,resched_curr函数就是设置调度标志位。这里不对虚拟运行时间的计算做分析。

__pick_first_entity函数:

struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq)
{
	struct rb_node *left = cfs_rq->rb_leftmost;

	if (!left)
		return NULL;

	return rb_entry(left, struct sched_entity, run_node);
}

可以看到这个函数里其实就是将二叉树最左侧的节点取出来,那说明二叉树里已经按照某种规则排好序了,排序的位置在哪里呢?入手点是cfs_rq,这个结构是在哪被排序的?根据什么排序的?查了下资料,最后找到__enqueue_entity、entity_before函数,作用就是就是根据vruntime把信息存入二叉树,最左侧的是最需要被执行的进程信息。
__enqueue_entity函数:

static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
{
	struct rb_node **link = &cfs_rq->tasks_timeline.rb_node;
	struct rb_node *parent = NULL;
	struct sched_entity *entry;
	int leftmost = 1;

	/*
	 * Find the right place in the rbtree:
	 */
	while (*link) {
		parent = *link;
		entry = rb_entry(parent, struct sched_entity, run_node);
		/*
		 * We dont care about collisions. Nodes with
		 * the same key stay together.
		 */
		if (entity_before(se, entry)) {
			link = &parent->rb_left;
		} else {
			link = &parent->rb_right;
			leftmost = 0;
		}
	}

	/*
	 * Maintain a cache of leftmost tree entries (it is frequently
	 * used):
	 */
	if (leftmost)
		cfs_rq->rb_leftmost = &se->run_node;

	rb_link_node(&se->run_node, parent, link);
	rb_insert_color(&se->run_node, &cfs_rq->tasks_timeline);
}

entity_before函数:

static inline int entity_before(struct sched_entity *a,
				struct sched_entity *b)
{
	return (s64)(a->vruntime - b->vruntime) < 0;
}

这样就可以确定排序是根据vruntime(虚拟运行时间)。

那又是在哪里调用的__enqueue_entity函数呢?

在这里插入图片描述
这是调用__enqueue_entity的一条路,还有其他的路,没有查找了就。

调用resched_curr函数设置调度标志位后,并没有马上就切换到需要运行的进程上下文中,目前还在时钟中断的上下文中,等中断结束之后才会调用schedule函数进行真正的进程上下文切换。

以上分析,若有错误,还望见谅。

与君共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值