时钟

http://www.ibm.com/developerworks/cn/linux/l-cn-timerm/?S_TACT=105AGX52&S_CMP=reg-ccid

http://blog.csdn.net/dog250/article/details/5303566

http://www.ibm.com/developerworks/cn/linux/l-cn-clocks/

先搞清楚两个概念:

超时:表示将在一段时间之后发生的事件,但可以且通常都会在发生之前取消,如:网络传输超时的设置。分辨率对超时定时器并不是很重要。

定时器:用于实现时序。使用 timer 类型的定时器往往要求在精确的时钟条件下完成特定的事件,通常是周期性的并且依赖超时机制进行处理。例如设备驱动通常会定时读写设备

          来进行数据交互。


/**
 * __run_timers - run all expired timers (if any) on this CPU.
 * @base: the timer vector to be processed.
 *
 * This function cascades all vectors and executes all expired timer
 * vectors.
 */
static inline void __run_timers(struct tvec_base *base)
{
	struct timer_list *timer;

	spin_lock_irq(&base->lock);
	while (time_after_eq(jiffies, base->timer_jiffies)) {  //处理所有从时间点timer_jiffies 到 时间点jiffies的事件。
		struct list_head work_list;
		struct list_head *head = &work_list;
		int index = base->timer_jiffies & TVR_MASK; //计算第一组的索引位置

		/*
		 * Cascade timers:
		 */
		if (!index &&
			(!cascade(base, &base->tv2, INDEX(0))) &&               //cascade用于从指定组取得定时器补充前一组。
				(!cascade(base, &base->tv3, INDEX(1))) &&
					!cascade(base, &base->tv4, INDEX(2)))
			cascade(base, &base->tv5, INDEX(3));                    //如果前组都已经是空的了,那么就将第五组的向前移动(因为第五组的时间到期时间实在是太晚,因此一般都不会东它们。)    
		++base->timer_jiffies;                 //timer_jiffiers记录的是一个时间点,这个时间点之前到期的定时器都已经处理过了。
		list_replace_init(base->tv1.vec + index, &work_list); //第一组位于索引位置的所有定时器都转移到一个临时链表中,从原来的数据结构中删除。
		while (!list_empty(head)) {                           //分别执行各个定时器的处理程序
			void (*fn)(unsigned long);
			unsigned long data;

			timer = list_first_entry(head, struct timer_list,entry);
			fn = timer->function;
			data = timer->data;

			timer_stats_account_timer(timer);

			base->running_timer = timer;
			detach_timer(timer, 1);

			spin_unlock_irq(&base->lock);
			call_timer_fn(timer, fn, data);
			spin_lock_irq(&base->lock);
		}
	}
	base->running_timer = NULL;
	spin_unlock_irq(&base->lock);
}





struct timer_list {
    /*
     * All fields that change during normal runtime grouped to the
     * same cacheline
     */
    struct list_head entry;
    unsigned long expires;
    struct tvec_base *base;

    void (*function)(unsigned long);
    unsigned long data;

    int slack;

#ifdef CONFIG_TIMER_STATS
    int start_pid;
    void *start_site;
    char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
    struct lockdep_map lockdep_map;
#endif
};


struct tvec_base {
    spinlock_t lock;
    struct timer_list *running_timer;
    unsigned long timer_jiffies;
    unsigned long next_timer;
    struct tvec_root tv1;
    struct tvec tv2;
    struct tvec tv3;
    struct tvec tv4;
    struct tvec tv5;
} ____cacheline_aligned;

 

asmlinkage void __init start_kernel(void)
{

	tick_init();


	init_timers();
	hrtimers_init();
	softirq_init();
	timekeeping_init();
	time_init();
	profile_init();


	if (late_time_init)
		late_time_init();
	sched_clock_init();

}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值