2013-01-14 41 views
10

Khi bộ hẹn giờ được tạo với API add_timer hết hạn và chức năng được chỉ định tại cấu trúc bộ đếm thời gian chạy, trong bối cảnh nào nó chạy? Liệu nó có làm gián đoạn bối cảnh hay bối cảnh của một số tiến trình hạt nhân?Chức năng hẹn giờ hạt nhân Linux chạy trong bối cảnh nào?

+3

OS gì bạn đang nói về? Nếu bạn có nghĩa là Linux và bộ đếm thời gian hạt nhân của nó, thì đó là bối cảnh ngắt khi nhận xét về 'add_timer()' trong 'linux/timer.c':" Hạt nhân sẽ thực hiện một hàm gọi lại -> hàm (-> dữ liệu) ** từ ngắt thời gian ** tại -> hết hạn trong tương lai. " Mặc dù trình xử lý ngắt có thể chạy trong ngữ cảnh quá trình trong một số hạt nhân, tôi sẽ không khuyên bạn nên đếm nó. – Eugene

+0

Xin chào, Xin lỗi, dĩ nhiên là nhân Linux. cảm ơn. – user1977760

Trả lời

7

Đó là tất nhiên trong bối cảnh ngắt, chính xác hơn, trong bối cảnh softirq, xem dưới đây (kernel/timer.c):

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 
} 
Các vấn đề liên quan