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

2021-09-07 12:31:01 字數 4386 閱讀 8392

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

1.  jiffies

核心用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); 

2.  struct timeval

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

[cpp]view plain

copy

struct timeval ; 

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

3.  struct timespec

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作為時間單位。

4.  struct ktime

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時間子系統之二 表示時間的單位和結構

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

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

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

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

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