Linux時間子系統之二 表示時間的單位和結構

2021-07-09 11:32:30 字數 4588 閱讀 8907

人們習慣用於表示時間的方法是:年、月、日、時、分、秒、毫秒、星期等等,但是在核心中,為了軟體邏輯和**的方便性,它使用了一些不同的時間表示方法,並為這些表示方法定義了相應的變數和資料結構,本節的內容就是闡述這些表示方法的意義和區別。

核心用jiffies變數記錄系統啟動以來經過的時鐘滴答數,它的宣告如下:

[cpp]view plain

copy

extern u64 __jiffy_data jiffies_64;  

extern unsigned long

volatile __jiffy_data jiffies;  

可見,在32位的系統上,jiffies是乙個32位的無符號數,系統每過1/hz秒,jiffies的值就會加1,最終該變數可能會溢位,所以核心同時又定義了乙個64位的變數jiffies_64,鏈結的指令碼保證jiffies變數和jiffies_64變數的記憶體位址是相同的,通常,我們可以直接訪問jiffies變數,但是要獲得jiffies_64變數,必須通過輔助函式get_jiffies_64來實現。jiffies是核心的低精度定時器的計時單位,所以核心配置的hz數決定了低精度定時器的精度,如果hz數被設定為1000,那麼,低精度定時器(timer_list)的精度就是1ms=1/1000秒。因為jiffies變數可能存在溢位的問題,所以在用基於jiffies進行比較時,應該使用以下輔助巨集來實現:

[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)  

同時,核心還提供了一些輔助函式用於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);  

timeval由秒和微秒組成,它的定義如下:

[cpp]view plain

copy

struct timeval ;  

__kernel_time_t

和 __kernel_suseconds_t 實際上都是long型的整數。gettimeofday和settimeofday使用timeval作為時間單位。

timespec由秒和納秒組成,它的定義如下:

[cpp]view plain

copy

struct timespec ;  

同樣地,核心也提供了一些輔助函式用於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作為時間單位。

linux的通用時間架構用ktime來表示時間,為了相容32位和64位以及big-little endian系統,ktime結構被定義如下:

[cpp]view plain

copy

union ktime  tv;  

#endif

};  

64位的系統可以直接訪問tv64欄位,單位是納秒,32位的系統則被拆分為兩個字段:sec和nsec,並且照顧了大小端的不同。高精度定時器通常用ktime作為計時單位。下面是一些輔助函式用於計算和轉換:

[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); 

Linux時間子系統之二 表示時間的單位和結構

人們習慣用於表示時間的方法是 年 月 日 時 分 秒 毫秒 星期等等,但是在核心中,為了軟體邏輯和 的方便性,它使用了一些不同的時間表示方法,並為這些表示方法定義了相應的變數和資料結構,本節的內容就是闡述這些表示方法的意義和區別。1.jiffies 核心用jiffies變數記錄系統啟動以來經過的時鐘...

Linux時間子系統之時間的表示

在linux核心中,為了相容原有的 或者符合某種規範,並且還要滿足當前精度日益提高的要求,實現了多種與時間相關但用於不同目的的資料結構 核心用jiffies 64全域性變數記錄系統自啟動以來經過了多少次tick。它的宣告如下 位於kernel time timer.c中 visible u64 ji...

linux 時間子系統 二 時間系統的組成

時間輪是linux kernel處理核心低精度定時器的機制,由週期的定時器中斷驅動。定時器中斷以配置的hz引數為頻率產生,在中斷中更新系統時間jiffies,摘取到期的定時器執行,更新時間輪時間。clock source 硬體計數器的一種抽象,它為系統提供一種時間線,通過時間線,每乙個動作都可以確定...