人們習(xí)慣用于表示時(shí)間的方法是:年、月、日、時(shí)、分、秒、毫秒、星期等等,但是在內(nèi)核中,為了軟件邏輯和代碼的方便性,它使用了一些不同的時(shí)間表示方法,并為這些表示方法定義了相應(yīng)的變量和數(shù)據(jù)結(jié)構(gòu),本節(jié)的內(nèi)容就是闡述這些表示方法的意義和區(qū)別。
/*****************************************************************************************************/
聲明:本博內(nèi)容均由http://blog.csdn.net/droidphone原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處,謝謝!
/*****************************************************************************************************/
1. ?jiffies
內(nèi)核用jiffies變量記錄系統(tǒng)啟動(dòng)以來經(jīng)過的時(shí)鐘滴答數(shù),它的聲明如下:
[cpp]?view plain?copy
extern?u64?__jiffy_data?jiffies_64;??
extern?unsigned?long?volatile?__jiffy_data?jiffies;??
可見,在32位的系統(tǒng)上,jiffies是一個(gè)32位的無符號(hào)數(shù),系統(tǒng)每過1/HZ秒,jiffies的值就會(huì)加1,最終該變量可能會(huì)溢出,所以內(nèi)核同時(shí)又定義了一個(gè)64位的變量jiffies_64,鏈接的腳本保證jiffies變量和jiffies_64變量的內(nèi)存地址是相同的,通常,我們可以直接訪問jiffies變量,但是要獲得jiffies_64變量,必須通過輔助函數(shù)get_jiffies_64來實(shí)現(xiàn)。jiffies是內(nèi)核的低精度定時(shí)器的計(jì)時(shí)單位,所以內(nèi)核配置的HZ數(shù)決定了低精度定時(shí)器的精度,如果HZ數(shù)被設(shè)定為1000,那么,低精度定時(shí)器(timer_list)的精度就是1ms=1/1000秒。因?yàn)閖iffies變量可能存在溢出的問題,所以在用基于jiffies進(jìn)行比較時(shí),應(yīng)該使用以下輔助宏來實(shí)現(xiàn):
[cpp]?view plain?copy
time_after(a,b)??
time_before(a,b)??
time_after_eq(a,b)??
time_before_eq(a,b)??
time_in_range(a,b,c)??
同時(shí),內(nèi)核還提供了一些輔助函數(shù)用于jiffies和毫秒以及納秒之間的轉(zhuǎn)換:
[cpp]?view plain?copy
unsigned?int?jiffies_to_msecs(const?unsigned?long?j);??
unsigned?int?jiffies_to_usecs(const?unsigned?long?j);??
unsigned?long?msecs_to_jiffies(const?unsigned?int?m);??
unsigned?long?usecs_to_jiffies(const?unsigned?int?u);??
2. ?struct timeval
timeval由秒和微秒組成,它的定義如下:
[cpp]?view plain?copy
struct?timeval?{??
__kernel_time_t?????tv_sec;?????/*?seconds?*/??
__kernel_suseconds_t????tv_usec;????/*?microseconds?*/??
};??
__kernel_time_t 和__kernel_suseconds_t 實(shí)際上都是long型的整數(shù)。gettimeofday和settimeofday使用timeval作為時(shí)間單位。
3. ?struct timespec
timespec由秒和納秒組成,它的定義如下:
[cpp]?view plain?copy
struct?timespec?{??
__kernel_time_t?tv_sec;?????????/*?seconds?*/??
long????????tv_nsec;????????/*?nanoseconds?*/??
};??
同樣地,內(nèi)核也提供了一些輔助函數(shù)用于jiffies、timeval、timespec之間的轉(zhuǎn)換:
[cpp]?view plain?copy
static?inline?int?timespec_equal(const?struct?timespec?*a,?const?struct?timespec?*b);??
static?inline?int?timespec_compare(const?struct?timespec?*lhs,?const?struct?timespec?*rhs);??
static?inline?int?timeval_compare(const?struct?timeval?*lhs,?const?struct?timeval?*rhs);??
extern?unsigned?long?mktime(const?unsigned?int?year,?const?unsigned?int?mon,??
const?unsigned?int?day,?const?unsigned?int?hour,??
const?unsigned?int?min,?const?unsigned?int?sec);??
extern?void?set_normalized_timespec(struct?timespec?*ts,?time_t?sec,?s64?nsec);??
static?inline?struct?timespec?timespec_add(struct?timespec?lhs,?struct?timespec?rhs);??
static?inline?struct?timespec?timespec_sub(struct?timespec?lhs,?struct?timespec?rhs);??
static?inline?s64?timespec_to_ns(const?struct?timespec?*ts);??
static?inline?s64?timeval_to_ns(const?struct?timeval?*tv);??
extern?struct?timespec?ns_to_timespec(const?s64?nsec);??
extern?struct?timeval?ns_to_timeval(const?s64?nsec);??
static?__always_inline?void?timespec_add_ns(struct?timespec?*a,?u64?ns);??
[cpp]?view plain?copy
unsigned?long?timespec_to_jiffies(const?struct?timespec?*value);??
void?jiffies_to_timespec(const?unsigned?long?jiffies,?struct?timespec?*value);??
unsigned?long?timeval_to_jiffies(const?struct?timeval?*value);??
void?jiffies_to_timeval(const?unsigned?long?jiffies,?struct?timeval?*value);??
timekeeper中的xtime字段用timespec作為時(shí)間單位。
4. ?struct ktime
linux的通用時(shí)間架構(gòu)用ktime來表示時(shí)間,為了兼容32位和64位以及big-little endian系統(tǒng),ktime結(jié)構(gòu)被定義如下:
[cpp]?view plain?copy
union?ktime?{??
s64?tv64;??
#if?BITS_PER_LONG?!=?64?&&?!defined(CONFIG_KTIME_SCALAR)??
struct?{??
#?ifdef?__BIG_ENDIAN??
s32?sec,?nsec;??
#?else??
s32?nsec,?sec;??
#?endif??
}?tv;??
#endif??
};??
64位的系統(tǒng)可以直接訪問tv64字段,單位是納秒,32位的系統(tǒng)則被拆分為兩個(gè)字段:sec和nsec,并且照顧了大小端的不同。高精度定時(shí)器通常用ktime作為計(jì)時(shí)單位。下面是一些輔助函數(shù)用于計(jì)算和轉(zhuǎn)換:
[cpp]?view plain?copy
ktime_t?ktime_set(const?long?secs,?const?unsigned?long?nsecs);???
ktime_t?ktime_sub(const?ktime_t?lhs,?const?ktime_t?rhs);???
ktime_t?ktime_add(const?ktime_t?add1,?const?ktime_t?add2);???
ktime_t?ktime_add_ns(const?ktime_t?kt,?u64?nsec);???
ktime_t?ktime_sub_ns(const?ktime_t?kt,?u64?nsec);???
ktime_t?timespec_to_ktime(const?struct?timespec?ts);???
ktime_t?timeval_to_ktime(const?struct?timeval?tv);???
struct?timespec?ktime_to_timespec(const?ktime_t?kt);???
struct?timeval?ktime_to_timeval(const?ktime_t?kt);???
s64?ktime_to_ns(const?ktime_t?kt);???
int?ktime_equal(const?ktime_t?cmp1,?const?ktime_t?cmp2);???
s64?ktime_to_us(const?ktime_t?kt);???
s64?ktime_to_ms(const?ktime_t?kt);???
ktime_t?ns_to_ktime(u64?ns); ?
?
評(píng)論
查看更多