2013-01-14 23 views
10

add_timer API'sı ile oluşturulmuş bir zamanlayıcı sona erdiğinde ve zamanlayıcı yapısında atanan işlev ne zaman çalışır? Bağlam mı yoksa bazı çekirdek süreç bağlamı mı? Bu kesme bağlamda elbetteLinux çekirdek zamanlayıcı işlevi hangi bağlamda çalışır?

+3

? Linux ve onun çekirdek zamanlayıcılarını kastediyorsanız, o zaman "linux/timer.c" ifadesindeki add_timer() 'inin yorumu olarak interrupt bağlamıdır:" Çekirdek bir -> fonksiyonu (-> veri) geri çağırır ** zamanlayıcı kesmeden ** -> gelecekte sona eriyor. Kesme işleyicileri bazı çekirdeklerde işlem bağlamında çalışabilir olsa da, üzerinde saymayı önermem. – Eugene

+0

Merhaba, Üzgünüm, elbette Linux çekirdeği. Teşekkürler. – user1977760

cevap

7

, daha doğrusu SoftIRQ bağlamda, (çekirdek/timer.c) aşağıya bakın:

sen neden bahsediyorsun OS
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)) { 
       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(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); 
       while (!list_empty(head)) { 
         void (*fn)(unsigned long); 
         unsigned long data; 
         bool irqsafe; 

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

         timer_stats_account_timer(timer); 

         base->running_timer = timer; 
         detach_expired_timer(timer, base); 

         if (irqsafe) { 
           spin_unlock(&base->lock); 
           call_timer_fn(timer, fn, data); // <=========== HERE 
           spin_lock(&base->lock); 
         } else { 
           spin_unlock_irq(&base->lock); 
           call_timer_fn(timer, fn, data); // <============ HERE 
           spin_lock_irq(&base->lock); 
         } 
       } 
     } 
     base->running_timer = NULL; 
     spin_unlock_irq(&base->lock); 
} 


/* 
* This function runs timers and the timer-tq in bottom half context. 
*/ 
static void run_timer_softirq(struct softirq_action *h) 
{ 
     struct tvec_base *base = __this_cpu_read(tvec_bases); 

     hrtimer_run_pending(); 

     if (time_after_eq(jiffies, base->timer_jiffies)) 
       __run_timers(base); 
} 

void __init init_timers(void) 
{ 
     int err; 

     /* ensure there are enough low bits for flags in timer->base pointer */ 
     BUILD_BUG_ON(__alignof__(struct tvec_base) & TIMER_FLAG_MASK); 

     err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE, 
           (void *)(long)smp_processor_id()); 
     init_timer_stats(); 

     BUG_ON(err != NOTIFY_OK); 
     register_cpu_notifier(&timers_nb); 
     open_softirq(TIMER_SOFTIRQ, run_timer_softirq); // <============= HERE 
} 
İlgili konular