W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
內(nèi)核代碼能一直獲取一個(gè)當(dāng)前時(shí)間的表示, 通過(guò)查看 jifies 的值. 常常地, 這個(gè)值只代表從最后一次啟動(dòng)以來(lái)的時(shí)間, 這個(gè)事實(shí)對(duì)驅(qū)動(dòng)來(lái)說(shuō)無(wú)關(guān), 因?yàn)樗纳芷谑芟抻谙到y(tǒng)的 uptime. 如所示, 驅(qū)動(dòng)可以使用 jiffies 的當(dāng)前值來(lái)計(jì)算事件之間的時(shí)間間隔(例如, 在輸入驅(qū)動(dòng)中從單擊中區(qū)分雙擊或者計(jì)算超時(shí)). 簡(jiǎn)單地講, 查看 jiffies 幾乎一直是足夠的, 當(dāng)你需要測(cè)量時(shí)間間隔. 如果你需要對(duì)短時(shí)間流失的非常精確的測(cè)量, 處理器特定的寄存器來(lái)幫忙了( 盡管它們帶來(lái)嚴(yán)重的移植性問(wèn)題 ).
它是非常不可能一個(gè)驅(qū)動(dòng)會(huì)需要知道墻上時(shí)鐘時(shí)間, 以月, 天, 和小時(shí)來(lái)表達(dá)的; 這個(gè)信息常常只對(duì)用戶程序需要, 例如 cron 和 syslogd. 處理真實(shí)世界的時(shí)間常常最好留給用戶空間, 那里的 C 庫(kù)提供了更好的支持; 另外, 這樣的代碼常常太策略相關(guān)以至于不屬于內(nèi)核. 有一個(gè)內(nèi)核函數(shù)轉(zhuǎn)變一個(gè)墻上時(shí)鐘時(shí)間到一個(gè) 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);
重復(fù):直接在驅(qū)動(dòng)中處理墻上時(shí)鐘時(shí)間往往是一個(gè)在實(shí)現(xiàn)策略的信號(hào), 并且應(yīng)當(dāng)因此而被置疑.
雖然你不會(huì)一定處理人可讀的時(shí)間表示, 有時(shí)你需要甚至在內(nèi)核空間中處理絕對(duì)時(shí)間. 為此, <linux/time.h> 輸出了 do_gettimeofday 函數(shù). 當(dāng)被調(diào)用時(shí), 它填充一個(gè) struct timeval 指針 -- 和在 gettimeofday 系統(tǒng)調(diào)用中使用的相同 -- 使用類似的秒和毫秒值. do_gettimeofday 的原型是:
#include <linux/time.h>
void do_gettimeofday(struct timeval *tv);
這段源代碼聲明 do_gettimeofday 有" 接近毫秒的精度", 因?yàn)樗儐?wèn)時(shí)間硬件當(dāng)前 jiffy 多大比例已經(jīng)流失. 這個(gè)精度每個(gè)體系都不同, 但是, 因?yàn)樗蕾噷?shí)際使用中的硬件機(jī)制. 例如, 一些 m68knommu 處理器, Sun3 系統(tǒng), 和其他 m68k 系統(tǒng)不能提供大于 jiffy 的精度. Pentium 系統(tǒng), 另一方面, 提供了非??焖俸途_的小于嘀噠的測(cè)量, 通過(guò)讀取本章前面描述的時(shí)戳計(jì)數(shù)器.
當(dāng)前時(shí)間也可用( 盡管使用 jiffy 的粒度 )來(lái)自 xtime 變量, 一個(gè) struct timespec 值. 不鼓勵(lì)這個(gè)變量的直接使用, 因?yàn)殡y以原子地同時(shí)存取這 2 個(gè)字段. 因此, 內(nèi)核提供了實(shí)用函數(shù) current_kernel_time:
#include <linux/time.h>
struct timespec current_kernel_time(void);
用來(lái)以各種方式獲取當(dāng)前時(shí)間的代碼, 可以從由 O' Reilly 提供的 FTP 網(wǎng)站上的源碼文件的 jit ("just in time") 模塊獲得. jit 創(chuàng)建了一個(gè)文件稱為 /proc/currentime, 當(dāng)讀取時(shí), 它以 ASCII 碼返回下列項(xiàng):
當(dāng)前的 jiffies 和 jiffies_64 值, 以 16 進(jìn)制數(shù)的形式.
如同 do_gettimeofday 返回的相同的當(dāng)前時(shí)間.
由 current_kernel_time 返回的 timespec.
我們選擇使用一個(gè)動(dòng)態(tài)的 /proc 文件來(lái)保持樣板代碼為最小 -- 它不值得創(chuàng)建一整個(gè)設(shè)備只是返回一點(diǎn)兒文本信息.
這個(gè)文件連續(xù)返回文本行只要這個(gè)模塊加載著; 每次 read 系統(tǒng)調(diào)用收集和返回一套數(shù)據(jù), 為更好閱讀而組織為 2 行. 無(wú)論何時(shí)你在少于一個(gè)時(shí)鐘嘀噠內(nèi)讀多個(gè)數(shù)據(jù)集, 你將看到 do_gettimeofday 之間的差別, 它詢問(wèn)硬件, 并且其他值僅在時(shí)鐘嘀噠時(shí)被更新.
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 件有趣的事情要注意. 首先, 這個(gè) current_kernel_time 值, 盡管以納秒來(lái)表示, 只有時(shí)鐘嘀噠的粒度; do_gettimeofday 持續(xù)報(bào)告一個(gè)稍晚的時(shí)間但是不晚于下一個(gè)時(shí)鐘嘀噠. 第二, 這個(gè) 64-位的 jiffies 計(jì)數(shù)器有 高 32-位字集合的最低有效位. 這是由于 INITIAL_JIFFIES 的缺省值, 在啟動(dòng)時(shí)間用來(lái)初始化計(jì)數(shù)器, 在啟動(dòng)時(shí)間后幾分鐘內(nèi)強(qiáng)加一個(gè)低字溢出來(lái)幫助探測(cè)與這個(gè)剛好溢出相關(guān)的問(wèn)題. 這個(gè)在計(jì)數(shù)器中的初始化偏好沒(méi)有效果, 因?yàn)?jiffies 與墻上時(shí)鐘時(shí)間無(wú)關(guān). 在 /proc/uptime 中, 這里內(nèi)核從計(jì)數(shù)器中抽取 uptime, 初始化偏好在轉(zhuǎn)換前被去除.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: