歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux hrtimer分析--未配置高精度模式

Linux hrtimer分析--未配置高精度模式

日期:2017/2/28 15:55:14   编辑:Linux教程

本文分析了Linux2.6.29中hrtimer的實現。

Linux2.6中實現了一種新的定時器hrtimer。與傳統定時器使用時間輪算法不同,hrtimer使用了紅黑樹算法。hrtimer本身可以配置成高精度和普通精度兩種,在單CPU系統和多CPU系統中的實現也有區別。這裡先分析最簡單的配置成普通精度、單CPU的情況。配置成高精度的情況見後續文章。

1. 時鐘源的定義

為了實現hrtimer,Linux為系統中每一個CPU定義了一個hrtimer_cpu_base,這個結構體的定義如下:

  1. struct hrtimer_cpu_base {
  2. raw_spinlock_t lock;
  3. struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; //時鐘源 #define HRTIMER_MAX_CLOCK_BASES 2
  4. #ifdef CONFIG_HIGH_RES_TIMERS
  5. ktime_t expires_next;
  6. int hres_active;
  7. int hang_detected;
  8. unsigned long nr_events;
  9. unsigned long nr_retries;
  10. unsigned long nr_hangs;
  11. ktime_t max_hang_time;
  12. #endif
  13. };
  14. <p> </p><pre class="cpp" name="code">struct hrtimer_clock_base {
  15. struct hrtimer_cpu_base *cpu_base;
  16. clockid_t index;
  17. struct rb_root active;
  18. struct rb_node *first;
  19. ktime_t resolution;
  20. ktime_t (*get_time)(void);
  21. ktime_t softirq_time;
  22. #ifdef CONFIG_HIGH_RES_TIMERS
  23. ktime_t offset;
  24. #endif
  25. };

在hrtimer.c中,有為每個CPU具體定義hrtimer_cpu_base的代碼:

  1. DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
  2. {
  3. .clock_base =
  4. {
  5. {
  6. .index = CLOCK_REALTIME,
  7. .get_time = &ktime_get_real,
  8. .resolution = KTIME_LOW_RES,
  9. },
  10. {
  11. .index = CLOCK_MONOTONIC,
  12. .get_time = &ktime_get,
  13. .resolution = KTIME_LOW_RES,
  14. },
  15. }
  16. };

1.1 時鐘源類型

可以看出,每個CPU都必須定義兩個時鐘源:REALTIME和MONOTONIC。REALTIME代表實時時鐘,MONOTONIC代表單調遞增時鐘。兩者的區別在於,當用戶更改系統時間時,REALTIME時鐘會收到影響,但MONOTONIC不受影響。這可以從它們兩個的get_time函數指針看出來,REALTIME時鐘指向的是ktime_get_real,MONOTONIC指向的是ktime_get。

時鐘源的結構體定義為struct hrtimer_clock_base,其中有兩個域struct rb_node *first和struct rb_root active,這兩個域維護了hrtimer的紅黑樹。也就是說,每一個hrtimer_clock_base都維護了自己的一個紅黑樹。

hrtimer在初始化時,都需要加入到某一個時鐘源的紅黑樹中,這個時鐘源要麼是REALTIME,要麼是MONOTONIC,這個關聯通過struct hrtimer的base域實現。

  1. struct hrtimer {
  2. struct rb_node node;
  3. ktime_t _expires;
  4. ktime_t _softexpires;
  5. enum hrtimer_restart (*function)(struct hrtimer *);
  6. struct hrtimer_clock_base *base;
  7. unsigned long state;
  8. #ifdef CONFIG_TIMER_STATS
  9. int start_pid;
  10. void *start_site;
  11. char start_comm[16];
  12. #endif
  13. };
Copyright © Linux教程網 All Rights Reserved