linux内核调度子系统随笔(二)

1. 优先级的内核表示

用户空间可以通过nice命令设置进程的静态优先级;

进程的nice值在-20到+19之间;值越低表示优先级越高;

内核使用0~139来表示内部优先级;同样值越低优先级越高;

#define MAX_USER_RT_PRIO    100
#define MAX_RT_PRIO        MAX_USER_RT_PRIO //最大实时优先级

#define MAX_PRIO        (MAX_RT_PRIO + 40)         //最大优先级
#define DEFAULT_PRIO        (MAX_RT_PRIO + 20) //默认优先级

#define NICE_TO_PRIO(nice)	(MAX_RT_PRIO + (nice) + 20) //nice值转优先级
#define PRIO_TO_NICE(prio)	((prio) - MAX_RT_PRIO - 20) 
#define TASK_NICE(p)		PRIO_TO_NICE((p)->static_prio)

2. 计算优先级

动态优先级: task_struct->prio, 普通优先级:task_struct->normal_prio; 静态优先级:task_struct->static_prio;

 static_prio是计算的起点,内核计算其他优先级,仅需p->prio=effective_prio(p);

static inline int rt_policy(int policy)
{
	if (policy == SCHED_FIFO || policy == SCHED_RR)
		return 1;
	return 0;
}

static inline int task_has_rt_policy(struct task_struct *p)
{
	return rt_policy(p->policy);
}

static inline int normal_prio(struct task_struct *p)
{
	int prio;

	if (task_has_rt_policy(p))
		//由于更高的rt_priority值表示更高的实时优先级,而内核恰好相反表示;
		prio = MAX_RT_PRIO-1 - p->rt_priority; 
	else
		prio = __normal_prio(p);//return p->static_prio;
	return prio;
}


static int effective_prio(struct task_struct *p)
{
	p->normal_prio = normal_prio(p);
	/*
	 如果是实时进程或已经提高到了实时优先级,则优先级保持不变,否则返回普通优先级;
	 */
	if (!rt_prio(p->prio))
		return p->normal_prio;
	return p->prio;
}

3. 计算负荷权重

 进程的重要性不仅由优先级指定,还需要考虑task_struct->se.load;的负荷权重;

struct load_weight {
	unsigned long weight; //权重值
    unsigned long inv_weight;//用于计算负荷权重除的结果;
};

 

set_load_weight负责根据进程类型及静态优先级计算负荷权重;

static const int prio_to_weight[40] = {
 /* -20 */     88761,     71755,     56483,     46273,     36291,
 /* -15 */     29154,     23254,     18705,     14949,     11916,
 /* -10 */      9548,      7620,      6100,      4904,      3906,
 /*  -5 */      3121,      2501,      1991,      1586,      1277,
 /*   0 */      1024,       820,       655,       526,       423,
 /*   5 */       335,       272,       215,       172,       137,
 /*  10 */       110,        87,        70,        56,        45,
 /*  15 */        36,        29,        23,        18,        15,
};

/*
 * Inverse (2^32/x) values of the prio_to_weight[] array, precalculated.
 *
 * In cases where the weight does not change often, we can use the
 * precalculated inverse to speed up arithmetics by turning divisions
 * into multiplications:
 */
static const u32 prio_to_wmult[40] = {
 /* -20 */     48388,     59856,     76040,     92818,    118348,
 /* -15 */    147320,    184698,    229616,    287308,    360437,
 /* -10 */    449829,    563644,    704093,    875809,   1099582,
 /*  -5 */   1376151,   1717300,   2157191,   2708050,   3363326,
 /*   0 */   4194304,   5237765,   6557202,   8165337,  10153587,
 /*   5 */  12820798,  15790321,  19976592,  24970740,  31350126,
 /*  10 */  39045157,  49367440,  61356676,  76695844,  95443717,
 /*  15 */ 119304647, 148102320, 186737708, 238609294, 286331153,
};

static void set_load_weight(struct task_struct *p)
{
	int prio = p->static_prio - MAX_RT_PRIO;
	struct load_weight *load = &p->se.load; //获取权重

	/*
	 * 若是空闲态,加载权重为最小值
	 */
	if (p->policy == SCHED_IDLE) {
		load->weight = scale_load(WEIGHT_IDLEPRIO);
		load->inv_weight = WMULT_IDLEPRIO;
		return;
	}

    //利用转换表将优先级转为权重;
	load->weight = scale_load(prio_to_weight[prio]);
	load->inv_weight = prio_to_wmult[prio];
}

每降低一个nice值,则多获取10%的cpu时间,每升高一个nice值,则放弃10%的cpu时间;故将优先级转换为权重值;转换表见prio_to_weight;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天未及海宽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值