linux內核時間管理(一) : 時間概念和延遲操作

內核中的時間概念

HZ:
Linux 核心每隔固定週期會發出timer interrupt (IRQ 0),HZ是用來定義每一秒有幾次timer interrupts。舉例來說,HZ爲1000,代表每秒有1000次timer interrupts

jiffies:
全局變量jiffies用於記錄系統啓動以來產生的節拍的總數。
啓動時,jiffies初始化爲0,此後每次時鐘中斷處理程序都會增加該變量的值。
linux提供了4個宏來比較節拍計數

#include <linux/jiffies.h> 
#define time_after(a, b)       // b >  a
#define time_before(a, b)      // b <  a
#define time_after_eq(a, b)    // b >= a
#define time_before_eq(a, b)   // b <= a

時間獲取

驅動程序中一般不需要知道牆鍾時間(也就是年月日的時間)。但驅動可能需要處理絕對時間。
爲此,內核提供了兩個結構體,都定義在

   struct timeval { 
      time_t tv_sec; /* seconds */ 
      suseconds_t tv_usec; /* microseconds */ 
    }; 

(2)採用秒和納秒值保存時間。

struct timespec { 
      time_t  tv_sec; /* seconds */ 
      long tv_nsec; /* nanoseconds */ 
 }; 

(3)用do_gettimeofday()用於獲得timeval

#include <linux/time.h> 
void do_gettimeofday(struct timeval *tv); 

(4) current_kernel_time() 用於獲得timespec

#include <linux/time.h> 
struct timespec current_kernel_time(void);

延遲操作

1.長延遲
(1)忙等待
如果對延遲的精確度要求不高,最簡單的方法是實現一個監視jiffies計時器的循環。

unsigned long delay = jiffies + 5*HZ;
while(time_before(jiffies, delay))
      cpu_relax();

(2)超時

#include <linux/sched.h> 
signed long schedule_timeout(signed long timeout); 

timeout是用jiffies表示的延遲時間,正常值返回0.
schedule_timeout在使用前需要設置當前進程狀態。

set_current_state(TASK_INTERRUPTIBLE); 
schedule_timeout(2*HZ); /* 睡2秒 */  

進程經過2秒後會被喚醒。
第一行調用set_current_state已設置當前進程狀態,調度器只有在超時到期且其狀態爲TASK_RUNNING時纔會運行這個進程。如果不希望被用戶空間打斷,可以將進程狀態設置爲TASK_UNINTERRUPTIBLE。

(3)讓出處理器

while(time_before(jiffies, j1)) 
      schedule(); 

在等待期間可以讓出處理器,減少CPU的負擔。

2.短延遲
對於那些最多幾十個毫秒的延遲,不需要依賴時間滴答

#include <Linux/delay.h>  
void ndelay(unsigned long nsecs); /*延遲納秒 */ 
void udelay(unsigned long usecs); /*延遲微秒 */ 
void mdelay(unsigned long msecs); /*延遲毫秒 */ 

這三個延遲函數均是忙等待函數,在延遲過程中無法運行其他任務。 它們的實現使用了軟件循環。

實現毫秒級(或者更長)延遲還有一種方法,這種方法不涉及忙等待

#include <Linux/delay.h>  
void msleep(unsigned int millisecs); /*休眠毫秒 */ 

void ssleep(unsigned int seconds); /*休眠秒 */ 
unsigned long msleep_interruptible(unsigned int millisecs);/*休眠毫秒,中斷可以喚醒*/ 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章