__run_timers() -- 处理全部超时定时器

__run_timers() -- 处理全部超时定时器

run_timer_softirq() --> __run_timers()

/usr/src/linux-2.6.19/kernel/timer.c

static inline void __run_timers(tvec_base_t *base)
{
    structtimer_list *timer;

    spin_lock_irq(&base->lock);
    /*处理所有已经超时的定时器*/
    while (time_after_eq(jiffies, base->timer_jiffies)) {
        structlist_headwork_list;
        structlist_head *head = &work_list;
        int index = base->timer_jiffies & TVR_MASK;           //(0)   

        /*
         * Cascade timers:
         */
        if (!index &&
            (!cascade(base, &base->tv2, INDEX(0))) &&
            (!cascade(base, &base->tv3, INDEX(1))) &&
            !cascade(base, &base->tv4, INDEX(2)))
            cascade(base, &base->tv5, INDEX(3));
        ++base->timer_jiffies;
        list_replace_init(base->tv1.vec + index, &work_list); //(1)
        /*处理base->tv1.vec[index]链表上的所有定时器*/
        while (!list_empty(head)) {
            void (*fn)(unsigned long);
            unsigned long data;

            timer = list_entry(head->next, structtimer_list, entry);
            fn = timer->function;
            data = timer->data;

            set_running_timer(base, timer);
            detach_timer(timer, 1);
            spin_unlock_irq(&base->lock);
            {
                intpreempt_count = preempt_count();
                fn(data);//在不带锁的情况下执行定时器函数
                if (preempt_count != preempt_count()) {
                    printk(KERN_WARNING "huh, entered %p "
                           "with preempt_count %08x, exited"
                           " with %08x?\n",
                           fn, preempt_count,
                           preempt_count());
                    BUG();
                }
            }
            spin_lock_irq(&base->lock);
        }
    }
    set_running_timer(base, NULL);
    spin_unlock_irq(&base->lock);
}


(1)
TVR_MASK = 255 = 11111111
--------------------------------------
#define TVR_MASK (TVR_SIZE - 1) 
#define TVR_SIZE (1 << TVR_BITS)
#define TVR_BITS (CONFIG_BASE_SMALL ? 6 : 8)

CONFIG_BASE_SMALL=0

(2) 根据base->timer_jiffies获取tv1所管理的数组的一个元素 -- 一个定时器队列

 

转载于:https://www.cnblogs.com/coucar/p/3176751.html

你可能感兴趣的:(数据结构与算法)