人們習慣用于表示時間的方法是:年、月、日、時、分、秒、毫秒、星期等等,但是在內核中,為了軟件邏輯和代碼的方便性,它使用了一些不同的時間表示方法,并為這些表示方法定義了相應的變量和數(shù)據(jù)結構,本節(jié)的內容就是闡述這些表示方法的意義和區(qū)別。
/*****************************************************************************************************/
聲明:本博內容均由http://blog.csdn.net/droidphone原創(chuàng),轉載請注明出處,謝謝!
/*****************************************************************************************************/
1. ?jiffies
內核用jiffies變量記錄系統(tǒng)啟動以來經(jīng)過的時鐘滴答數(shù),它的聲明如下:
[cpp]?view plain?copy
extern?u64?__jiffy_data?jiffies_64;??
extern?unsigned?long?volatile?__jiffy_data?jiffies;??
可見,在32位的系統(tǒng)上,jiffies是一個32位的無符號數(shù),系統(tǒng)每過1/HZ秒,jiffies的值就會加1,最終該變量可能會溢出,所以內核同時又定義了一個64位的變量jiffies_64,鏈接的腳本保證jiffies變量和jiffies_64變量的內存地址是相同的,通常,我們可以直接訪問jiffies變量,但是要獲得jiffies_64變量,必須通過輔助函數(shù)get_jiffies_64來實現(xiàn)。jiffies是內核的低精度定時器的計時單位,所以內核配置的HZ數(shù)決定了低精度定時器的精度,如果HZ數(shù)被設定為1000,那么,低精度定時器(timer_list)的精度就是1ms=1/1000秒。因為jiffies變量可能存在溢出的問題,所以在用基于jiffies進行比較時,應該使用以下輔助宏來實現(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ù)用于jiffies和毫秒以及納秒之間的轉換:
[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 實際上都是long型的整數(shù)。gettimeofday和settimeofday使用timeval作為時間單位。
3. ?struct timespec
timespec由秒和納秒組成,它的定義如下:
[cpp]?view plain?copy
struct?timespec?{??
__kernel_time_t?tv_sec;?????????/*?seconds?*/??
long????????tv_nsec;????????/*?nanoseconds?*/??
};??
同樣地,內核也提供了一些輔助函數(shù)用于jiffies、timeval、timespec之間的轉換:
[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作為時間單位。
4. ?struct ktime
linux的通用時間架構用ktime來表示時間,為了兼容32位和64位以及big-little endian系統(tǒng),ktime結構被定義如下:
[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)則被拆分為兩個字段:sec和nsec,并且照顧了大小端的不同。高精度定時器通常用ktime作為計時單位。下面是一些輔助函數(shù)用于計算和轉換:
[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); ?
?
評論
查看更多