Linux内核源码解析 - CFS调度算法

本文详细探讨了Linux内核中的 Completely Fair Scheduler (CFS) 调度算法,从进程描述符的数据结构开始,重点关注了vruntime变量及其在调度过程中的作用。通过分析vruntime的计算、更新过程,揭示了CFS如何维护归一化处理的调度时长以实现公平调度。文章还讨论了nice、weight、prio之间的关系,并简述了红黑树在CFS中的应用,指出其用于保存就绪态进程并保证O(1)的取操作时间复杂度。
摘要由CSDN通过智能技术生成

进程调度,那么先从进程描述符的数据结构开始

struct task_struct {
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	void *stack;
	atomic_t usage;
	unsigned int flags;	/* per process flags, defined below */
	unsigned int ptrace;

	int lock_depth;		/* BKL lock depth */

        ...

	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;
    
        ...
}

在进程描述符中注意到sched_entity类型的se成员变量,这个是进程调度器的实体结构,同时我们也看到prio相关的参数(进程优先级)。我们来看下sched_entity的数据结构

struct sched_entity {
	struct load_weight	load;		/* for load-balancing */
	struct rb_node		run_node;
	struct list_head	group_node;
	unsigned int		on_rq;

	u64			exec_start;
	u64			sum_exec_runtime;
	u64			vruntime;
	u64			prev_sum_exec_runtime;

	u64			last_wakeup;
	u64			avg_overlap;

	u64			nr_migrations;

	u64			start_runtime;
	u64			avg_wakeup;

...
};

我们关注下其中一些重要的参数,后面会重点分析。 vruntime变量字面意思虚拟运行时间,可以理解成进程实际调度运行时间(以ms为单位)的标准化处理的结果,作为抽象出来的指标。下面来看其相关的操作。

static void update_curr(struct cfs_rq *cfs_rq)
{
	struct sched_entity *curr = cfs_rq->curr;
	u64 now = rq_of(cfs_rq)->clock;
	unsigned long delta_exec;

	if (unlikely(!curr))
		return;

	/*
	 * Get the amount of time the current task was running
	 * since the last time we changed load (this cannot
	 * overflow on 32 bits):
	 */
	delta_exec = (unsigned long)(n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值