Welcome 微信登录

首页 / 操作系统 / Linux / Linux Kernel中如何使用高精度timer(hrtimer)

前面已经讲过,高精度timer是通过hrtimer来实现的(见 http://www.linuxidc.com/Linux/2012-03/55892.htm ),hrtimer通过可编程定时器来现,在等待时,不占用CPU。在用户态,只要我们调用usleep,则线程在kernel态执行时,则使用hrtimer进行不占CPU的等待。在Kernel中如何使用的呢?先看看eventpoll.c中的ep_poll函数:
  1. static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,  
  2.            int maxevents, long timeout)  
  3. {  
  4.     int res = 0, eavail, timed_out = 0;  
  5.     unsigned long flags;  
  6.     long slack = 0;  
  7.     wait_queue_t wait;  
  8.     ktime_t expires, *to = NULL;  
  9.   
  10.     if (timeout > 0) {  
  11.         struct timespec end_time = ep_set_mstimeout(timeout);  
  12.   
  13.         slack = select_estimate_accuracy(&end_time);  
  14.         to = &expires;  
  15.         *to = timespec_to_ktime(end_time);  
  16.     } else if (timeout == 0) {  
  17.         /* 
  18.          * Avoid the unnecessary trip to the wait queue loop, if the 
  19.          * caller specified a non blocking operation. 
  20.          */  
  21.         timed_out = 1;  
  22.         spin_lock_irqsave(&ep->lock, flags);  
  23.         goto check_events;  
  24.     }  
  25.   
  26. fetch_events:  
  27.     spin_lock_irqsave(&ep->lock, flags);  
  28.   
  29.     if (!ep_events_available(ep)) {  
  30.         /* 
  31.          * We don"t have any available event to return to the caller. 
  32.          * We need to sleep here, and we will be wake up by 
  33.          * ep_poll_callback() when events will become available. 
  34.          */  
  35.         init_waitqueue_entry(&wait, current);  
  36.         __add_wait_queue_exclusive(&ep->wq, &wait);  
  37.   
  38.         for (;;) {  
  39.             /* 
  40.              * We don"t want to sleep if the ep_poll_callback() sends us 
  41.              * a wakeup in between. That"s why we set the task state 
  42.              * to TASK_INTERRUPTIBLE before doing the checks. 
  43.              */  
  44.             set_current_state(TASK_INTERRUPTIBLE);  
  45.             if (ep_events_available(ep) || timed_out)  
  46.                 break;  
  47.             if (signal_pending(current)) {  
  48.                 res = -EINTR;  
  49.                 break;  
  50.             }  
  51.   
  52.             spin_unlock_irqrestore(&ep->lock, flags);  
  53.             if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))  
  54.                 timed_out = 1;  
  55.   
  56.             spin_lock_irqsave(&ep->lock, flags);  
  57.         }  
  58.         __remove_wait_queue(&ep->wq, &wait);  
  59.   
  60.         set_current_state(TASK_RUNNING);  
  61.     }  
  62. check_events:  
  63.     /* Is it worth to try to dig for events ? */  
  64.     eavail = ep_events_available(ep);  
  65.   
  66.     spin_unlock_irqrestore(&ep->lock, flags);  
  67.   
  68.     /* 
  69.      * Try to transfer events to user space. In case we get 0 events and 
  70.      * there"s still timeout left over, we go trying again in search of 
  71.      * more luck. 
  72.      */  
  73.     if (!res && eavail &&  
  74.         !(res = ep_send_events(ep, events, maxevents)) && !timed_out)  
  75.         goto fetch_events;  
  76.   
  77.     return res;  
  78. }  
  • 1
  • 2
  • 下一页
ARM Linux系统的时钟机制Linux Kernel 及 binder mmap实现相关资讯      Linux Kernel 
  • Linux Kernel 3.14系列结束支持  (今 14:24)
  • Linux kernel 2.6.32 LTS 将于下个  (01月31日)
  • 怎样在 CentOS 7 上安装 Kernel 4.  (05/15/2015 11:28:39)
  • Linux Kernel 开发报告 25 周年版  (09月10日)
  • Linux Kernel 4.1.15发布  (12/15/2015 20:54:13)
  • Linux Kernel stable 3.19.7/4.0.2  (05/07/2015 08:50:31)
本文评论 查看全部评论 (0)
表情: 姓名: 字数