Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22439
  • 博文数量: 8
  • 博客积分: 20
  • 博客等级: 民兵
  • 技术积分: 149
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-01 11:02
个人简介

no no no

文章分类

全部博文(8)

文章存档

2013年(8)

我的朋友

分类: LINUX

2013-07-03 23:21:51

1. jiffies
HZ是每秒产生的时钟中断数。
jiffies是系统启动后,时钟中断的次数可通过它来计算时间。可见分辨率低。
系统通过它来取得当前时间,也用来处理一些低分辨率的时间处理,如鼠标双击。

2. 高精度计数
绝大多数cpu有一个随着时钟周期不断递增的计数寄存器,这是完成高分辨率计数的唯一方法。比如x86上有名的TSC时间戳计数器。
内核提供了 cycles_t get_cycles(void) ,它可在任何平台上取得计数寄存器。如果没有则返回0。

3. 延迟执行代码
1) 长延时:需要推后执行的时间要多个时钟ticks
   ----忙等jiffies:

点击(此处)折叠或打开

  1. while (time_before(jiffies, j1))
  2.     cpu_relax();
    问题:严重降低性能:如果内核非抢占,此代码会锁住系统;如果进入代码前禁用了中断,则jiffies不更新,系统挂死。
   ----让出处理器:
    

点击(此处)折叠或打开

  1. while (time_before(jiffies, j1)) {
  2.     schedule();
  3. }
    虽然貌似让系统重新调度,但实际上此进程仍处于可运行态,仍可能被调度到。

   ----超时等待
   利用等待队列,可将等待队列等待的条件划明界限。即jiffies到则从等待队列上唤醒。内核函数为:
  
    long wait_event_timeout(wait_queue_head_t q, condition, long timeout);
   内核还提供了 schedule_timeout(),避免手工申请等待队列。但它需要先设置进程状态,如:
   

点击(此处)折叠或打开

  1. set_current_state(TASK_INTERRUPTIBLE);
  2. schedule_timeout (delay);
2) 短延迟
   内核提供udelay实现微秒级的延迟。它根据系统引导时计算出的处理器速度确定循环忙等的次数。

   毫秒级的延迟还可以调用sleep系函数,这些函数不忙等。

4. 内核定时器
与延迟执行区别是,定时器设置后本身流程继续,定时到走的流程与本身无关,为异步运行。所以定时器函数执行时,可能处于非进程上下文中。in_interrupt()判断是否处理中断上下文。in_atomic()则是不可调度点的标志(中断,软中断,自旋锁)。非进程上下文的函数需要按以下规则处理:
   a. 不可访问用户空间,因为无进程上下文;
   b. current无意义;
   c. 不可睡眠或调度,比如调用kmalloc(..., GFP_KERNEL)、信号量等
定时函数要额外注意并发处理保护。

5. tasklet
用于稍后某时执行函数,不指定时间。也通过软中断实现。
同一tasklet执行不会在多cpu上同时进行。
执行的时机:如果不忙则立即执行;最晚不超过一个tick

6. 工作队列
功能类似tasklet,但区别如下:
   a. 工作队列运行在内核线程中,因此可以睡眠;
   b. 工作队列可以更长的延迟。

阅读(610) | 评论(0) | 转发(0) |
0

上一篇:ldd 6 阻塞I/O

下一篇:ldd 8 内存分配

给主人留下些什么吧!~~