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

來源:互聯網
上載者:User

 轉自:http://blog.csdn.net/walkingman321/article/details/6133171

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

 

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

1.     時鐘源的定義

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

struct hrtimer_cpu_base {raw_spinlock_tlock;struct hrtimer_clock_baseclock_base[HRTIMER_MAX_CLOCK_BASES];  //時鐘源 #define HRTIMER_MAX_CLOCK_BASES 2#ifdef CONFIG_HIGH_RES_TIMERSktime_texpires_next;inthres_active;inthang_detected;unsigned longnr_events;unsigned longnr_retries;unsigned longnr_hangs;ktime_tmax_hang_time;#endif};

 

struct hrtimer_clock_base {struct hrtimer_cpu_base*cpu_base;clockid_tindex;struct rb_rootactive;struct rb_node*first;ktime_tresolution;ktime_t(*get_time)(void);ktime_tsoftirq_time;#ifdef CONFIG_HIGH_RES_TIMERSktime_toffset;#endif};

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

DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) ={.clock_base ={{.index = CLOCK_REALTIME,.get_time = &ktime_get_real,.resolution = KTIME_LOW_RES,},{.index = CLOCK_MONOTONIC,.get_time = &ktime_get,.resolution = KTIME_LOW_RES,},}};

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域實現。

struct hrtimer {struct rb_nodenode;ktime_t_expires;ktime_t_softexpires;enum hrtimer_restart(*function)(struct hrtimer *);struct hrtimer_clock_base*base;unsigned longstate;#ifdef CONFIG_TIMER_STATSintstart_pid;void*start_site;charstart_comm[16];#endif};

2. hrtimer的基本操作

      Linux的傳統定時器通過時間輪演算法實現(timer.c),但hrtimer通過紅/黑樹狀結構演算法實現。在struct hrtimer裡面有一個node域,類型為struct rb_node,這個域代表了hrtimer在紅/黑樹狀結構中的位置。

 2.1 hrtimer_start

hrtimer_start函數將一個hrtimer加入到一個按照到期時間排序的紅/黑樹狀結構中,其主要流程為:

int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);

       // 根據time和mode參數的值計算hrtimer的逾時時間,並設定到timer->expire域。

       // expire設定的是絕對時間,所以如果參數mode的值為HRTIMER_MODE_REL(即參數tim的值為相對時間),那麼需要將tim的值修正為絕對時間:

       //     expire = tim + timer->base->get_time()。(注意本文只研究單CPU的情況)

       //調用enqueue_hrtimer,將hrtimer加入到紅/黑樹狀結構中。

 

2.2 hrtimer的到期

      hrtimer在hrtimer_run_queues函數中判斷是否到期執行。hrtimer_run_queues <Called from hardirq context every jiffy>的調用鏈為:Linux的系統時鐘函數->update_process_times->run_local_timers->hrtimer_run_queues。

void hrtimer_run_queues(void)

       // 判斷是否是高精度模式,如果是高精度模式,立即返回。本文暫不考慮這種情況。

       // 對每一個時鐘源(REALTIME和MONOTONIC)的紅/黑樹狀結構,按到期先後順序檢查hrtimer,看它們是否到期(將定時器與時鐘源的softirq_time比較)。如果到期,就把這個到期的定時器取出,然後按照定時器的具體模式執行相應的操作:

      //如果定時器模式為HRTIMER_CB_SOFTIRQ,那麼將定時器搬到hrtimer_cpu_base的cb_pending隊列

      //調用__run_hrtimer,在__run_hrtimer中執行定時器的回呼函數。

 

在沒有配置高精度模式時,cb_pending隊列中的定時器會在TIMER_SOFTIRQ非強制中斷中執行。調用鏈為

run_timer_softirq->
hrtimer_run_pending(Called from timer softirq every jiffy)->

hrtimer_switch_to_hres->
tick_init_highres->
tick_switch_to_oneshot(hrtimer_interrupt)
<把hrtimer_interrupt賦值給dev->event_handler,即dev->event_handler = handler;>

 

2.3 hrtimer_cancel

       hrtimer_cancel函數的作用是刪除一個正在排隊的定時器。這裡分三種情況,一種是定時器已到期,並且設定了非強制中斷模式;第二種是沒有到期,還在紅/黑樹狀結構中;第三種是定時器正在執行。

         第一種情況,定時器被掛在hrtimer_cpu_base的cb_pending隊列中,所以需要把它從pending隊列中移出。

         第二種情況,定時器還在紅/黑樹狀結構中,那麼把它從紅/黑樹狀結構中移出。由於本文暫時只考慮高精度沒有開啟的情況,所以先不研究定時器正好排在紅/黑樹狀結構第一個時的情況(即代碼中調用hrtimer_force_reprogram函數的部分)。

         第三種情況刪除失敗,hrtimer_cancel函數會迴圈重試,等到定時器執行完的時候再刪除。(這在多CPU系統中可能會發生)

3.  未使能高精度模式時與傳統timer的區別

     1)傳統timer使用時間輪演算法,hrtimer使用紅/黑樹狀結構演算法。

     2)傳統timer在非強制中斷中執行,hrtimer在硬中斷中執行(update_process_times -> run_local_timers -> hrtimer_run_queues)。如果hrtimer設定了HRTIMER_CB_SOFTIRQ模式,那麼timer會被移到pending隊列,然後再由非強制中斷執行。

 

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.