Kernel中如何使用高精度timer(hrtimer)

來源:互聯網
上載者:User

 

   前面已經講過,高精度timer是通過hrtimer來實現的,hrtimer通過可程式化定時器來現,在等待時,不佔用CPU。

       在使用者態,只要我們調用usleep,則線程在kernel態執行時,則使用hrtimer進行不佔CPU的等待。

       在Kernel中如何使用的呢?

       先看看eventpoll.c中的ep_poll函數:

 

static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,   int maxevents, long timeout){int res = 0, eavail, timed_out = 0;unsigned long flags;long slack = 0;wait_queue_t wait;ktime_t expires, *to = NULL;if (timeout > 0) {struct timespec end_time = ep_set_mstimeout(timeout);slack = select_estimate_accuracy(&end_time);to = &expires;*to = timespec_to_ktime(end_time);} else if (timeout == 0) {/* * Avoid the unnecessary trip to the wait queue loop, if the * caller specified a non blocking operation. */timed_out = 1;spin_lock_irqsave(&ep->lock, flags);goto check_events;}fetch_events:spin_lock_irqsave(&ep->lock, flags);if (!ep_events_available(ep)) {/* * We don't have any available event to return to the caller. * We need to sleep here, and we will be wake up by * ep_poll_callback() when events will become available. */init_waitqueue_entry(&wait, current);__add_wait_queue_exclusive(&ep->wq, &wait);for (;;) {/* * We don't want to sleep if the ep_poll_callback() sends us * a wakeup in between. That's why we set the task state * to TASK_INTERRUPTIBLE before doing the checks. */set_current_state(TASK_INTERRUPTIBLE);if (ep_events_available(ep) || timed_out)break;if (signal_pending(current)) {res = -EINTR;break;}spin_unlock_irqrestore(&ep->lock, flags);if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))timed_out = 1;spin_lock_irqsave(&ep->lock, flags);}__remove_wait_queue(&ep->wq, &wait);set_current_state(TASK_RUNNING);}check_events:/* Is it worth to try to dig for events ? */eavail = ep_events_available(ep);spin_unlock_irqrestore(&ep->lock, flags);/* * Try to transfer events to user space. In case we get 0 events and * there's still timeout left over, we go trying again in search of * more luck. */if (!res && eavail &&    !(res = ep_send_events(ep, events, maxevents)) && !timed_out)goto fetch_events;return res;}

       看到上面的schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS)了嗎?它就是hrtimer中調用來執行等待逾時的函數

,其函數原型為:

/**
 * schedule_hrtimeout_range - sleep until timeout
 * @expires: timeout value (ktime_t)
 * @delta: slack in expires timeout (ktime_t)
 * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
 */
int __sched schedule_hrtimeout_range(ktime_t *expires, unsigned long delta,
         const enum hrtimer_mode mode)
{
 return schedule_hrtimeout_range_clock(expires, delta, mode,
           CLOCK_MONOTONIC);
}
      在ep_poll中,其slack和to的計算方法如下:

struct timespec end_time = ep_set_mstimeout(timeout);
slack = select_estimate_accuracy(&end_time);
to = &expires;
*to = timespec_to_ktime(end_time);

      如果你在Kernel中需要高精度timer,可以參照此方法實現自己的高精度timer逾時。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.