LDD3读书笔记(第8章 时间、延迟及延缓操作)

计时
#include <linux/param.h>
HZ
    HZ符号指出每秒钟产生的时钟滴答数。
#include <linux/jiffies.h>
volatile unsigned long jiffies
u64 jiffies_64
    jiffies_64变量会在每个时钟滴答递增,也就是说,它会在每秒递增HZ次。内核代码大部分情况下使用jiffies,在64位平台上,它和jiffies_64是一样的,而在32位平台上,jiffies是jiffies_64的低32位。
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);
    这些布尔表达式以安全方式比较jiffies,无需考虑计数器溢出的问题,也不必访问jiffies_64。
u64 get_jiffies_64(void);
    无竞态地获取jiffies_64的值。
#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表示的时间和其他表示法之间的转换。
#include <asm/msr.h>
rdtsc(low32,high32);
rdtscl(low32);
rdtscll(var32);
    x86专用宏,用来读取时间戳计数器。上述宏用两个32位字的形式读取该计数器,要么读取低32位,要么整个读取到一个long long型的变量中。
#include <linux/timex.h>
cycles_t get_cycles(void);
    以平台无关的方式返回时间戳计数器。如果CPU不提供时间戳特性,则返回0。
#include <linux/time.h>
unsigned long mktime{year,mon,day,h,m,s};
    根据6个无符号的int参数返回自Epoch以来的秒数。
void do_gettimeofday(struct timeval *tv);
    以自Epoch以来的秒数和毫秒数的形式返回当前时间,并且以硬件能提供的最好分辨率返回。在大多数平台上,分辨率是微秒或更好,但某些平台只能提供jiffies级的分辨率。
struct timespec current_kernel_time(void);
    以jiffies为分辨率返回当前时间。

延迟
#include <linux/wait.h>
long wait_event_interruptible_timeout(wait_queue_head_t *q,condition,signed long timeout);
    使当前进程休眠在等待队列上,并指出用jiffies表达的超时值。如果要进入不可中断休眠,则应使用schedule_timeout。
#include <linux/sched.h>
signed long schedule_timeout(signed long timeout);
    调用调度器,确保当前进程可在给定的超时值之后唤醒。调用者必须首先调用set_current_state将自己置于可中断或不可中断的休眠状态。
#include <linux/delay.h>
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
    引入整数的纳秒。微秒和毫秒级延迟。实际达到的延迟至少是请求的值,但可能更长。传入每个函数的参数不能超过平台相关的限制(通常是几千)。
void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds);
    使进程休眠给定的毫秒数(或使用ssleep休眠给定的秒数)。

内核定时器
#include <asm/hardirq.h>
int in_interrupt(void);
int in_atomic(void);
     返回布尔值以告知调用代码是否在中断上下文或者在原子上下文中执行。中断上下文在进程上下文之外,可能正处理硬件或软件中断。原子上下文是指不能进行调度的时间点,比如中断上下文或者拥有自旋锁时的进程上下文。
#include <linux/timer.h>
void init_timer(struct timer_list * timer);
struct timer_list TIMER_INITIALIZER(_function,_expires,_data);
    上面的函数以及静态声明定时器结构的宏是初始化timer_list数据结构的两种方式。
void add_timer(struct timer_list * timer);
注册定时器结构,以在当前CPU上运行。
int mod_timer(struct timer_list *timer,unsigend long expires);
    修改一个已经调度的定时器结构的到期时间。它也可以替代add_timer函数使用。
int timer_pending(struct timer_list * timer);
    返回布尔值的宏,用来判断给定的定时器结构是否已经被注册运行。
void del_timer(struct timer_list * timer);
void del_timer_sync(struct timer_list * timer);
    从活动定时器清单中删除一个定时器。后一个函数确保定时器不会在其他CPU上运行。

tasklet
#include <linux/interrupt.h>
DECLARE_TASKLET(name,func,data);
DECLARE_TASKLET_DISABLED(name,func,data);
void tasklet_init(struct tasklet_struct *t,void(*func)(unsigend long),unsigned long data);
    前面两个宏声明一个tasklet结构,而tasklet_init函数初始化一个通过分配或者其他途径获得的tasklet结构。第二个DESCLARE宏禁用给定的tasklet。
void tasklet_disable(struct tasklet_struct *t);
void tasklet_disable_nosync(struct tasklet_struct *t);
void tasklet_enable(struct tasklet_struct *t);
    禁用或重新启用某个tasklet。每次禁止都要匹配一次使能(我们可以禁用一个已经被禁用的tasklet)。tasklet_disable函数会在tasklet正在其他CPU上运行时等待,而nosync版本不会完成这个额外的步骤。
void tasklet_schedule(struct tasklet_struct *t);
void tasklet_hi_schedule(struct tasklet_struct *t);
    调度运行某个tasklet,可以是“通常”的tasklet或者一个高优先级的tasklet。当执行软件中断时,高优先级的tasklet会被首先处理,而通常的tasklet最后运行。
void tasklet_kill(struct tasklet_struct *t);
    如果指定的tasklet被调度运行,则将其从活动链表中删除。和tasklet_disable类似,该函数可在SMP系统上阻塞,以便等待正在其他CPU上运行的该tasklet终止。

工作队列
#include <linux/workqueue.h>
struct workqueue_strcut;
strcut work_struct;
    上述结构分别表示工作队列和工作入口项。
struct workqueue_struct *create_workqueue(const char *name);
struct workqueue_struct *create_singlethread_workqueue(const char *name);
void destroy_workqueue(struct workqueue_struct *queue);
    用于创建和销毁工作队列的函数。调用create_workqueue将创建一个队列,且系统中的每个处理器上都会运行一个工作线程;相反,create_singlethread_workqueue只会创建单个工作进程。
DECLARE_WORK(name,void(*function)(void *),void *data);
INIT_WORK(struct work_struct *work,void(*function)(void *),void *data);
PREPARE_WORK(struct work_strcut *work,void(*function)(void *),void *data);
    用于声明和初始化工作队列入口项的宏。
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);
    用来安排工作以便从工作队列中执行的函数。
int cancel_delayed_work(strcut work_struct *work);
void flush_workqueue(struct workqueue_struct *queue);
    使用cancel_delayed_work可从工作队列中删除一个入口项,flush_workqueue确保系统中任何地方都不会运行任何工作队列入口项。
int schedule_work(struct work_struct *work);
int schedule_delayed_work(struct work_struct *work,unsigned long delay);
void flush_schedule_work(void);
    使用共享工作队列的函数。

你可能感兴趣的:(LDD3读书笔记(第8章 时间、延迟及延缓操作))