时间子系统7_高分辨率定时器处理(一)

2014-11-24 02:42:02 · 作者: · 浏览: 3
//	高分辨率下的定时器软中断
//	函数任务:
//		1.关中断下,运行所有hrtimer
//	注:
//		在hrtimers_init中,open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);  
1.1 static void run_hrtimer_softirq(struct softirq_action *h)
{
 	//遍历运行所有到期的hrtimer
	hrtimer_peek_ahead_timers();
}

//	遍历运行hrtimer
//	函数任务:
//		1.关中断
//		2.运行hrtimer
//	调用路径:run_hrtimer_softirq->hrtimer_peek_ahead_timers
1.2 void hrtimer_peek_ahead_timers(void)
{
	unsigned long flags;
	//关中断
	local_irq_save(flags);
	hrtimer_interrupt(&__get_cpu_var(tick_cpu_device)->evtdev);
	local_irq_restore(flags);
}

//	高分辨率tick device事件处理函数
//		遍历执行本cpu上的hrtimer
//	调用路径:run_hrtimer_softirq->....->hrtimer_interrupt
//	函数任务:
//		1.遍历时钟基础
//			1.1 运行到期的hrtimer
//		2.如果处理完所有hrtimer,关闭时钟事件设备,退出
//		3.重复步骤1,最多遍历3次
//		4.更新统计信息
//			4.1 cpu_base->nr_hangs统计一次hrtimer未能处理完所有hrtimer的次数
//			4.2 cpu_base->hang_detected指示有hrtimer待处理
//			4.3 cpu_base->max_hang_time记录hrtimer_interrupt花费的最大时间,即hrtimer可能被延迟的最大时间
//		5.根据花费的时间计算时钟事件设备下一次到期的时间
//			5.1 如果处理hrtimer花费时间超过1ms,推迟下一次到期时间为1ms后
//			5.2 否则下一次到期时间为花费的时间
1.3 void hrtimer_interrupt(struct clock_event_device *dev)
{
	struct hrtimer_cpu_base *cpu_base = &__get_cpu_var(hrtimer_bases);
	struct hrtimer_clock_base *base;
	ktime_t expires_next, now, entry_time, delta;
	int i, retries = 0;

	cpu_base->nr_events++;
	dev->next_event.tv64 = KTIME_MAX;

	entry_time = now = ktime_get();
retry:
	expires_next.tv64 = KTIME_MAX;
	//防止此段时间内其他cpu的hrtimer迁移到本cpu时
	raw_spin_lock(&cpu_base->lock);
	cpu_base->expires_next.tv64 = KTIME_MAX;
	base = cpu_base->clock_base;
	//遍历所有时钟基础的hrtime
	for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
		ktime_t basenow;
		struct rb_node *node;
		//时钟基础的时间与实际时间可能有偏移,hrtimer的到期时间为实际时间的绝对值
		basenow = ktime_add(now, base->offset);

		while ((node = base->
first)) { struct hrtimer *timer; timer = rb_entry(node, struct hrtimer, node); //如果当前hrtimer还没有到期 if (basenow.tv64 < hrtimer_get_softexpires_tv64(timer)) { ktime_t expires; //更新时钟事件下一次到期时间 expires = ktime_sub(hrtimer_get_expires(timer), base->offset); if (expires.tv64 < expires_next.tv64) expires_next = expires; break; } //否则立即执行定时器 __run_hrtimer(timer, &basenow); } base++; } //更新时钟基础下一次到期时间 cpu_base->expires_next = expires_next; raw_spin_unlock(&cpu_base->lock); //没有要到期的hrtimer,关闭时间事件设备 if (expires_next.tv64 == KTIME_MAX || !tick_program_event(expires_next, 0)) { cpu_base->hang_detected = 0; return; } //防止一直处理hrtimer,最大遍历次数3 now = ktime_get(); cpu_base->nr_retries++; if (++retries < 3) goto retry; //有挂起的hrtimer需要处理 cpu_base->nr_hangs++; cpu_base->hang_detected = 1; //计算hrtimer_interrupt处理hrtimer花费的时间 delta = ktime_sub(now, entry_time); if (delta.tv64 > cpu_base->max_hang_time.tv64) cpu_base->max_hang_time = delta; //根据花费的时间计算时钟事件设备下一次到期的时间 // 如果处理hrtimer花费时间超过1ms,推迟下一次到期时间为1ms后 // 否则下一次到期时间为花费的时间 if (delta.tv64 > 100 * NSEC_PER_MSEC) expires_next = ktime_add_ns(now, 100 * NSEC_PER_MSEC); else expires_next = ktime_add(now, delta); tick_program_event(expires_next, 1); } // 运行hrtimer // 调用路径:hrtimer_interrupt->__run_hrtimer // 函数任务: // 1.从红黑树中删除hrtimer // 2.设置其为执行状态 // 3.执行hrtimer回调函数 // 3.1 如果hrtimer需要继续执行,重新建hrtimer加入到红黑树中 // 4.清除其正在执行标志 1.4 static void __run_hrtimer(struct hrtimer *timer, ktime_t *now) { struct hrtimer_clock_base *base = timer->base; struct hrtimer_cpu_base *cpu_base = base->cpu_base; enum hrtimer_restart (*fn)(struct hrtimer *); int restart; //从红黑树中删除hrtimer,设置其为执行状态 __remove_hrtimer(timer, base, HRTIMER_STATE_CALLBACK, 0);