歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> Linux內核分析之軟定時器筆記

Linux內核分析之軟定時器筆記

日期:2017/2/28 16:00:36   编辑:Linux內核

定時器是一種軟件功能,即允許在將來的某個時刻,函數在給定的時間間隔用完時被調用。超時表示與定時器相關的時間間隔已經用完的那個時刻。

linux上考慮兩種類型的定時器,即動態定時和間隔定時器。第一種類型由內核使用,而間隔定時器由進程在用戶態創建。

動態定時器

動態定時的主要數據結構是一個叫做tvec_bases的per cpu變量,他包含NR_CPUS個元素,系統中每個CPU都有一個。每個元素是一個tvec_base_t類型的數據結構,他包含相應CPU中處理動態定時器需要的所有數據。

  1. struct tvec_base {
  2. spinlock_t lock;
  3. struct timer_list *running_timer;
  4. unsigned long timer_jiffies;
  5. unsigned long next_timer;
  6. struct tvec_root tv1;
  7. struct tvec tv2;
  8. struct tvec tv3;
  9. struct tvec tv4;
  10. struct tvec tv5;
  11. } ____cacheline_aligned;

字段tv1的數據解雇為tvec_root_t類型,包含一個vec數組,這個數組由256個list_head元素組成(即256個動態定時器鏈表組成)。這個結構包含了在緊接著到來的255個節拍內將要到期的所有動態定時器。

字段tv2,tv3和tv4的數據結構都是tvec_t類型,該類型有一個數組vec。這些鏈表包含在緊接著到來的2^14-1/2^20-1以及2^26-1個節拍內將要到期的所有動態定時器。

字段tv5與前面的字段幾乎相同,但唯一區別就是vec數組的最後一項是一個大expires字段值得動態定時器鏈表。tv5從不需要從其他的數組補充。

動態定時器編程

1,申請timer_list結構並對其初始化,其中必須初始化的有expires,function

  1. struct timer_list {
  2. struct list_head entry;
  3. unsigned long expires;
  4. void (*function)(unsigned long);
  5. unsigned long data;
  6. struct tvec_base *base;
  7. #ifdef CONFIG_TIMER_STATS
  8. void *start_site;
  9. char start_comm[16];
  10. int start_pid;
  11. #endif
  12. #ifdef CONFIG_LOCKDEP
  13. struct lockdep_map lockdep_map;
  14. #endif
  15. };

2,調用init_timer函數初始化

該函數最終調用下面函數

  1. static void __init_timer(struct timer_list *timer,
  2. const char *name,
  3. struct lock_class_key *key)
  4. {
  5. timer->entry.next = NULL;
  6. timer->base = __raw_get_cpu_var(tvec_bases);
  7. #ifdef CONFIG_TIMER_STATS
  8. timer->start_site = NULL;
  9. timer->start_pid = -1;
  10. memset(timer->start_comm, 0, TASK_COMM_LEN);
  11. #endif
  12. lockdep_init_map(&timer->lockdep_map, name, key, 0);
  13. }

可看到初始化的幾個相關變量。

Copyright © Linux教程網 All Rights Reserved