7.2. 獲知當前時間

2018-02-24 15:49 更新

7.2.?獲知當前時間

內(nèi)核代碼能一直獲取一個當前時間的表示, 通過查看 jifies 的值. 常常地, 這個值只代表從最后一次啟動以來的時間, 這個事實對驅(qū)動來說無關, 因為它的生命周期受限于系統(tǒng)的 uptime. 如所示, 驅(qū)動可以使用 jiffies 的當前值來計算事件之間的時間間隔(例如, 在輸入驅(qū)動中從單擊中區(qū)分雙擊或者計算超時). 簡單地講, 查看 jiffies 幾乎一直是足夠的, 當你需要測量時間間隔. 如果你需要對短時間流失的非常精確的測量, 處理器特定的寄存器來幫忙了( 盡管它們帶來嚴重的移植性問題 ).

它是非常不可能一個驅(qū)動會需要知道墻上時鐘時間, 以月, 天, 和小時來表達的; 這個信息常常只對用戶程序需要, 例如 cron 和 syslogd. 處理真實世界的時間常常最好留給用戶空間, 那里的 C 庫提供了更好的支持; 另外, 這樣的代碼常常太策略相關以至于不屬于內(nèi)核. 有一個內(nèi)核函數(shù)轉(zhuǎn)變一個墻上時鐘時間到一個 jiffies 值, 但是:


#include <linux/time.h> 
unsigned long mktime (unsigned int year, unsigned int mon,
 unsigned int day, unsigned int hour,
 unsigned int min, unsigned int sec); 

重復:直接在驅(qū)動中處理墻上時鐘時間往往是一個在實現(xiàn)策略的信號, 并且應當因此而被置疑.

雖然你不會一定處理人可讀的時間表示, 有時你需要甚至在內(nèi)核空間中處理絕對時間. 為此, <linux/time.h> 輸出了 do_gettimeofday 函數(shù). 當被調(diào)用時, 它填充一個 struct timeval 指針 -- 和在 gettimeofday 系統(tǒng)調(diào)用中使用的相同 -- 使用類似的秒和毫秒值. do_gettimeofday 的原型是:


 #include <linux/time.h>
 void do_gettimeofday(struct timeval *tv);

這段源代碼聲明 do_gettimeofday 有" 接近毫秒的精度", 因為它詢問時間硬件當前 jiffy 多大比例已經(jīng)流失. 這個精度每個體系都不同, 但是, 因為它依賴實際使用中的硬件機制. 例如, 一些 m68knommu 處理器, Sun3 系統(tǒng), 和其他 m68k 系統(tǒng)不能提供大于 jiffy 的精度. Pentium 系統(tǒng), 另一方面, 提供了非??焖俸途_的小于嘀噠的測量, 通過讀取本章前面描述的時戳計數(shù)器.

當前時間也可用( 盡管使用 jiffy 的粒度 )來自 xtime 變量, 一個 struct timespec 值. 不鼓勵這個變量的直接使用, 因為難以原子地同時存取這 2 個字段. 因此, 內(nèi)核提供了實用函數(shù) current_kernel_time:


#include <linux/time.h>
struct timespec current_kernel_time(void);

用來以各種方式獲取當前時間的代碼, 可以從由 O' Reilly 提供的 FTP 網(wǎng)站上的源碼文件的 jit ("just in time") 模塊獲得. jit 創(chuàng)建了一個文件稱為 /proc/currentime, 當讀取時, 它以 ASCII 碼返回下列項:

  • 當前的 jiffies 和 jiffies_64 值, 以 16 進制數(shù)的形式.

  • 如同 do_gettimeofday 返回的相同的當前時間.

  • 由 current_kernel_time 返回的 timespec.

我們選擇使用一個動態(tài)的 /proc 文件來保持樣板代碼為最小 -- 它不值得創(chuàng)建一整個設備只是返回一點兒文本信息.

這個文件連續(xù)返回文本行只要這個模塊加載著; 每次 read 系統(tǒng)調(diào)用收集和返回一套數(shù)據(jù), 為更好閱讀而組織為 2 行. 無論何時你在少于一個時鐘嘀噠內(nèi)讀多個數(shù)據(jù)集, 你將看到 do_gettimeofday 之間的差別, 它詢問硬件, 并且其他值僅在時鐘嘀噠時被更新.


phon% head -8 /proc/currentime
0x00bdbc1f 0x0000000100bdbc1f 1062370899.630126
 1062370899.629161488
0x00bdbc1f 0x0000000100bdbc1f 1062370899.630150
 1062370899.629161488
0x00bdbc20 0x0000000100bdbc20 1062370899.630208
 1062370899.630161336
0x00bdbc20 0x0000000100bdbc20 1062370899.630233
 1062370899.630161336

在上面的屏幕快照中, 由 2 件有趣的事情要注意. 首先, 這個 current_kernel_time 值, 盡管以納秒來表示, 只有時鐘嘀噠的粒度; do_gettimeofday 持續(xù)報告一個稍晚的時間但是不晚于下一個時鐘嘀噠. 第二, 這個 64-位的 jiffies 計數(shù)器有 高 32-位字集合的最低有效位. 這是由于 INITIAL_JIFFIES 的缺省值, 在啟動時間用來初始化計數(shù)器, 在啟動時間后幾分鐘內(nèi)強加一個低字溢出來幫助探測與這個剛好溢出相關的問題. 這個在計數(shù)器中的初始化偏好沒有效果, 因為 jiffies 與墻上時鐘時間無關. 在 /proc/uptime 中, 這里內(nèi)核從計數(shù)器中抽取 uptime, 初始化偏好在轉(zhuǎn)換前被去除.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號