7.7. 快速參考

2018-02-24 15:49 更新

7.7.?快速參考

本章介紹了下面的符號(hào).

7.7.1.?時(shí)間管理

#include <linux/param.h>
HZ 

HZ 符號(hào)指定了每秒產(chǎn)生的時(shí)鐘嘀噠的數(shù)目.

#include <linux/jiffies.h>
volatile unsigned long jiffies;
u64 jiffies_64;

jiffies_64 變量每個(gè)時(shí)鐘嘀噠時(shí)被遞增; 因此, 它是每秒遞增 HZ 次. 內(nèi)核代碼幾乎常常引用 jiffies, 它在 64-位平臺(tái)和 jiffies_64 相同并且在 32-位平臺(tái)是它低有效的一半.

int time_after(unsigned long a, unsigned long b);
int time_before(unsigned long a, unsigned long b);
int time_after_eq(unsigned long a, unsigned long b);
int time_before_eq(unsigned long a, unsigned long b);

這些布爾表達(dá)式以一種安全的方式比較 jiffies, 沒有萬一計(jì)數(shù)器溢出的問題和不需要存取 jiffies_64.

u64 get_jiffies_64(void);

獲取 jiffies_64 而沒有競(jìng)爭(zhēng)條件.

#include <linux/time.h>
unsigned long timespec_to_jiffies(struct timespec *value);
void jiffies_to_timespec(unsigned long jiffies, struct timespec *value);
unsigned long timeval_to_jiffies(struct timeval *value);
void jiffies_to_timeval(unsigned long jiffies, struct timeval *value);

在 jiffies 和其他表示之間轉(zhuǎn)換時(shí)間表示.

#include <asm/msr.h>
rdtsc(low32,high32);
rdtscl(low32);
rdtscll(var32);

x86-特定的宏定義來讀取時(shí)戳計(jì)數(shù)器. 它們作為 2 半 32-位來讀取, 只讀低一半, 或者全部讀到一個(gè) long long 變量.

#include <linux/timex.h>
cycles_t get_cycles(void);

以平臺(tái)獨(dú)立的方式返回時(shí)戳計(jì)數(shù)器. 如果 CPU 沒提供時(shí)戳特性, 返回 0.

#include <linux/time.h>
unsigned long mktime(year, mon, day, h, m, s);

返回自 Epoch 以來的秒數(shù), 基于 6 個(gè) unsigned int 參數(shù).

void do_gettimeofday(struct timeval *tv);

返回當(dāng)前時(shí)間, 作為自 Epoch 以來的秒數(shù)和微秒數(shù), 用硬件能提供的最好的精度. 在大部分的平臺(tái)這個(gè)解決方法是一個(gè)微秒或者更好, 盡管一些平臺(tái)只提供 jiffies 精度.

struct timespec current_kernel_time(void);

返回當(dāng)前時(shí)間, 以一個(gè) jiffy 的精度.

7.7.2.?延遲

#include <linux/wait.h>
long wait_event_interruptible_timeout(wait_queue_head_t *q, condition, signed long timeout);

使當(dāng)前進(jìn)程在等待隊(duì)列進(jìn)入睡眠, 安裝一個(gè)以 jiffies 表達(dá)的超時(shí)值. 使用 schedule_timeout( 下面) 給不可中斷睡眠.

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

調(diào)用調(diào)度器, 在確保當(dāng)前進(jìn)程在超時(shí)到的時(shí)候被喚醒后. 調(diào)用者首先必須調(diào)用 set_curret_state 來使自己進(jìn)入一個(gè)可中斷的或者不可中斷的睡眠狀態(tài).

#include <linux/delay.h>
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);

引入一個(gè)整數(shù)納秒, 微秒和毫秒的延遲. 獲得的延遲至少是請(qǐng)求的值, 但是可能更多. 每個(gè)函數(shù)的參數(shù)必須不超過一個(gè)平臺(tái)特定的限制(常常是幾千).

void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds);

使進(jìn)程進(jìn)入睡眠給定的毫秒數(shù)(或者秒, 如果使 ssleep).

7.7.3.?內(nèi)核定時(shí)器

#include <asm/hardirq.h>
int in_interrupt(void);
int in_atomic(void);

返回一個(gè)布爾值告知是否調(diào)用代碼在中斷上下文或者原子上下文執(zhí)行. 中斷上下文是在一個(gè)進(jìn)程上下文之外, 或者在硬件或者軟件中斷處理中. 原子上下文是當(dāng)你不能調(diào)度一個(gè)中斷上下文或者一個(gè)持有一個(gè)自旋鎖的進(jìn)程的上下文.

#include <linux/timer.h>
void init_timer(struct timer_list * timer);
struct timer_list TIMER_INITIALIZER(_function, _expires, _data);

這個(gè)函數(shù)和靜態(tài)的定時(shí)器結(jié)構(gòu)的聲明是初始化一個(gè) timer_list 數(shù)據(jù)結(jié)構(gòu)的 2 個(gè)方法.

void add_timer(struct timer_list * timer);

注冊(cè)定時(shí)器結(jié)構(gòu)來在當(dāng)前 CPU 上運(yùn)行.

int mod_timer(struct timer_list *timer, unsigned long expires);

改變一個(gè)已經(jīng)被調(diào)度的定時(shí)器結(jié)構(gòu)的超時(shí)時(shí)間. 它也能作為一個(gè) add_timer 的替代.

int timer_pending(struct timer_list * timer);

宏定義, 返回一個(gè)布爾值說明是否這個(gè)定時(shí)器結(jié)構(gòu)已經(jīng)被注冊(cè)運(yùn)行.

void del_timer(struct timer_list * timer);
void del_timer_sync(struct timer_list * timer);

從激活的定時(shí)器鏈表中去除一個(gè)定時(shí)器. 后者保證這定時(shí)器當(dāng)前沒有在另一個(gè) CPU 上運(yùn)行.

7.7.4.?Tasklets 機(jī)制

#include <linux/interrupt.h>
DECLARE_TASKLET(name, func, data);
DECLARE_TASKLET_DISABLED(name, func, data);
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);

前 2 個(gè)宏定義聲明一個(gè) tasklet 結(jié)構(gòu), 而 tasklet_init 函數(shù)初始化一個(gè)已經(jīng)通過分配或其他方式獲得的 tasklet 結(jié)構(gòu). 第 2 個(gè) DECLARE 宏標(biāo)識(shí)這個(gè) tasklet 為禁止的.

void tasklet_disable(struct tasklet_struct *t);
void tasklet_disable_nosync(struct tasklet_struct *t);
void tasklet_enable(struct tasklet_struct *t);

禁止和使能一個(gè) tasklet. 每個(gè)禁止必須配對(duì)一個(gè)使能( 你可以禁止這個(gè) tasklet 即便它已經(jīng)被禁止). 函數(shù) tasklet_disable 等待 tasklet 終止如果它在另一個(gè) CPU 上運(yùn)行. 這個(gè)非同步版本不采用這個(gè)額外的步驟.

void tasklet_schedule(struct tasklet_struct *t);
void tasklet_hi_schedule(struct tasklet_struct *t);

調(diào)度一個(gè) tasklet 運(yùn)行, 或者作為一個(gè)"正常" tasklet 或者一個(gè)高優(yōu)先級(jí)的. 當(dāng)軟中斷被執(zhí)行, 高優(yōu)先級(jí) tasklets 被首先處理, 而正常 tasklet 最后執(zhí)行.

void tasklet_kill(struct tasklet_struct *t);

從激活的鏈表中去掉 tasklet, 如果它被調(diào)度執(zhí)行. 如同 tasklet_disable, 這個(gè)函數(shù)可能在 SMP 系統(tǒng)中阻塞等待 tasklet 終止, 如果它當(dāng)前在另一個(gè) CPU 上運(yùn)行.

7.7.5.?工作隊(duì)列

#include <linux/workqueue.h>
struct workqueue_struct;
struct work_struct;

這些結(jié)構(gòu)分別表示一個(gè)工作隊(duì)列和一個(gè)工作入口.

struct workqueue_struct *create_workqueue(const char *name);
struct workqueue_struct *create_singlethread_workqueue(const char *name);
void destroy_workqueue(struct workqueue_struct *queue);

創(chuàng)建和銷毀工作隊(duì)列的函數(shù). 一個(gè)對(duì) create_workqueue 的調(diào)用創(chuàng)建一個(gè)有一個(gè)工作者線程在系統(tǒng)中每個(gè)處理器上的隊(duì)列; 相反, create_singlethread_workqueue 創(chuàng)建一個(gè)有一個(gè)單個(gè)工作者進(jìn)程的工作隊(duì)列.

DECLARE_WORK(name, void (*function)(void *), void *data);
INIT_WORK(struct work_struct *work, void (*function)(void *), void *data);
PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);

聲明和初始化工作隊(duì)列入口的宏.

int queue_work(struct workqueue_struct queue, struct work_struct work);int queue_delayed_work(struct workqueue_struct queue, struct work_struct work, unsigned long delay);
從一個(gè)工作隊(duì)列對(duì)工作進(jìn)行排隊(duì)執(zhí)行的函數(shù).

int cancel_delayed_work(struct work_struct *work);
void flush_workqueue(struct workqueue_struct *queue);

使用 cancel_delayed_work 來從一個(gè)工作隊(duì)列中去除入口; flush_workqueue 確保沒有工作隊(duì)列入口在系統(tǒng)中任何地方運(yùn)行.

int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work, unsigned long delay);
void flush_scheduled_work(void);

使用共享隊(duì)列的函數(shù).

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)