11.定時器庫
定時器庫為DPDK執(zhí)行單元提供定時器服務,使得執(zhí)行單元可以為異步操作執(zhí)行回調(diào)函數(shù)。定時器庫的特性如下:
- 定時器可以周期執(zhí)行,也可以執(zhí)行一次。
- 定時器可以在一個核心加載并在另一個核心執(zhí)行。但是必須在調(diào)用rte_timer_reset()中指定它。
- 定時器提供高精度(取決于檢查本地核心的定時器到期的rte_timer_manage()的調(diào)用頻率)。
- 如果應用程序不需要,可以在編譯時禁用定時器,并且程序中不調(diào)用rte_timer_manage()來提高性能。
定時器庫使用rte_get_timer_cycles()獲取高精度事件定時器(HPET)或CPU時間戳計數(shù)器(TSC)提供的可靠時間參考。
該庫提供了添加,刪除和重新啟動定時器的接口。API基于BSD callout(),可能會有一些差異。詳細請參考callout手冊。
11.1.實現(xiàn)細節(jié)
定時器以每個邏輯核為基礎進行跟蹤,一個邏輯核上要維護的所有掛起的定時器,按照定時器到期順序插入到跳躍表數(shù)據(jù)結構。
所使用的跳躍表有十個層,表中的每個條目都以1/4的概率顯示在每個層上。這意味著所有條目都存在于第0層中,每4個條目中的1個條目存在于第一層,每16個中1個條目存在于第2層,等等。同時,這意味著從邏輯核的定時器列表中添加和刪除條目可以在log(n)時間內(nèi)完成,最多4 ^ 10個條目,即每個邏輯核約有1,000,000個定時器。
定時器結構包含一個稱為狀態(tài)的特殊字段,它是定時器狀態(tài)(stopped,pending,running,config)及其所有者(lcore id)的聯(lián)合體。根據(jù)定時器狀態(tài),我們可以知道定時器當前是否存在于列表中:
- STOPPED:沒有所有者,不再鏈表中。
- CONFIG:由一個邏輯核持有,其他邏輯核不能修改,是否存在于跳表中取決于以前的狀態(tài)。
- PENDING:由一個邏輯核持有,當前在跳表中。
- RUNNING:由一個邏輯核持有,當前在跳表中,不能由其他邏輯核修改。
不允許在定時器處于CONFIG或RUNNING狀態(tài)時復位或停止定時器。當修改定時器的狀態(tài)時,應使用CAP指令來保證狀態(tài)修改操作(狀態(tài)+所有者)是原子操作。
在rte_timer_manage()函數(shù)里面,跳躍表作為常規(guī)的鏈表,通過沿著包含所有計時器條目的第0層鏈表迭代,直到遇到尚未到期的條目為止。當列表中有條目,但是沒有任何條目定時器到期時,為了提高性能,第一個定時器條目的到期時間保存在每個邏輯和計時器列表結構本身內(nèi)部。在64位平臺上,可以直接檢查該值,而無需對整個結構進行鎖定。(由于到期時間維持為64位值,所以在32位平臺上無法直接對該值進行檢查,而不使用(CAS)指令或使用鎖機制,因此,一旦數(shù)據(jù)結構被上鎖,此額外的檢查將被跳過。)在64位和32位平臺上,在調(diào)用邏輯核的計時器列表為空的情況下,對rte_timer_manage()的調(diào)用將直接返回而不進行鎖定。=
11.2.用例
定時器庫用于定期調(diào)用,如垃圾收集器或某些狀態(tài)機(ARP,橋接等)。
11.3.參考
- callout manual :喚醒功能,提供定時器到期執(zhí)行的功能。
- HPET :有關高精度事件定時器(HPET)的信息。