調度子系統3_週期調度器

//	週期調度器
//	調用路徑:update_process_times->scheduler_tick
//	函數任務:
//		1.更新rq的clock
//		2.更新隊列負載
//		3.通知調度器類更新進程運行時間
//		4.更新下一次load balance的時間戳
//		5.觸發load balance
1.1 void scheduler_tick(void)
{
	int cpu = smp_processor_id();
	struct rq *rq = cpu_rq(cpu);
	//當前運行的進程
	struct task_struct *curr = rq->curr;
	raw_spin_lock(&rq->lock);
	//更新rq的clock
	update_rq_clock(rq);
	//更新隊列負載
	update_cpu_load_active(rq);
	//更新進程的運行時間
	curr->sched_class->task_tick(rq, curr, 0);
	raw_spin_unlock(&rq->lock);

#ifdef CONFIG_SMP
	//更新下一次load balance的時間戳
	rq->idle_balance = idle_cpu(cpu);
	//觸發load balance軟中斷
	trigger_load_balance(rq, cpu);
#endif
}


//	更新隊列負載(rq->cpu_load[])
//		每scheduler tick(TICK_NSEC)被調用一次
//	函數任務:
//		1.更新rq負載
//			1.1 通過CPU_LOAD_IDX_MAX個項記錄rq的歷史負載信息
//			1.2 更新方法
//				cpu_load[0] = load.weight
//				cpu_load[1] = (cpu_load[1]   + load.weight)/2
//				cpu_load[2] = (cpu_load[2]*3 + load.weight)/4
//				cpu_load[3] = (cpu_load[2]*7 + load.weight)/8
//		2.如果當前時間到達計算cpu負載的時間點
//			2.1 更新下一次計算cpu負載的時間點
//			2.2 計算cpu負載
//	調用路徑:scheduler_tick->update_cpu_load
2.1 static void update_cpu_load(struct rq *this_rq)
{
	//rq中所有se負載的總和
	unsigned long this_load = this_rq->load.weight;
	int i, scale;
	this_rq->nr_load_updates++;
	//通過CPU_LOAD_IDX_MAX個項記錄rq的歷史負載信息
	for (i = 0, scale = 1; i < CPU_LOAD_IDX_MAX; i++, scale += scale) {
		unsigned long old_load, new_load;

		old_load = this_rq->cpu_load[i];
		//rq中所有se的load.weight之和
		new_load = this_load;
		if (new_load > old_load)
			new_load += scale-1;
		//cpu_load[0] = load.weight
		//cpu_load[1] = (cpu_load[1]   + load.weight)/2
		//cpu_load[2] = (cpu_load[2]*3 + load.weight)/4
		//cpu_load[3] = (cpu_load[2]*7 + load.weight)/8
		//....
		this_rq->cpu_load[i] = (old_load*(scale-1) + new_load) >> i;
	}
	//到達計算cpu負載的時間點
	if (time_after_eq(jiffies, this_rq->calc_load_update)) {
		//更新下一次計算cpu負載的時間點
		this_rq->calc_load_update += LOAD_FREQ;
		//計算系統負載
		calc_load_account_active(this_rq);
	}
}
//	計算系統負載
//		系統負載考慮就緒狀態進程和不可中斷睡眠的進程(I/O)進程
//	調用路徑:update_cpu_load->calc_load_account_active
2.2 static void calc_load_account_active(struct rq *this_rq)
{
	long nr_active, delta;

	nr_active = this_rq->nr_running;	//就緒狀態的進程
	nr_active += (long) this_rq->nr_uninterruptible;	//不可中斷睡眠的進程

	if (nr_active != this_rq->calc_load_active) {	
		delta = nr_active - this_rq->calc_load_active;
		this_rq->calc_load_active = nr_active;
		atomic_long_add(delta, &calc_load_tasks);
	}
}

發佈了145 篇原創文章 · 獲贊 49 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章