Commit 7bb67439bf6bd3782f07f1d7be1e63406453d5de

Authored by Arjan van de Ven
1 parent 70bb08962e

select: Introduce a hrtimeout function

This patch adds a schedule_hrtimeout() function, to be used by select() and
poll() in a later patch. This function works similar to schedule_timeout()
in most ways, but takes a timespec rather than jiffies.

With a lot of contributions/fixes from Thomas

Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Showing 2 changed files with 67 additions and 0 deletions Side-by-side Diff

include/linux/hrtimer.h
... ... @@ -346,6 +346,8 @@
346 346 extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
347 347 struct task_struct *tsk);
348 348  
  349 +extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
  350 +
349 351 /* Soft interrupt function to run the hrtimer queues: */
350 352 extern void hrtimer_run_queues(void);
351 353 extern void hrtimer_run_pending(void);
... ... @@ -1677,4 +1677,70 @@
1677 1677 open_softirq(HRTIMER_SOFTIRQ, run_hrtimer_softirq);
1678 1678 #endif
1679 1679 }
  1680 +
  1681 +/**
  1682 + * schedule_hrtimeout - sleep until timeout
  1683 + * @expires: timeout value (ktime_t)
  1684 + * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
  1685 + *
  1686 + * Make the current task sleep until the given expiry time has
  1687 + * elapsed. The routine will return immediately unless
  1688 + * the current task state has been set (see set_current_state()).
  1689 + *
  1690 + * You can set the task state as follows -
  1691 + *
  1692 + * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
  1693 + * pass before the routine returns.
  1694 + *
  1695 + * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
  1696 + * delivered to the current task.
  1697 + *
  1698 + * The current task state is guaranteed to be TASK_RUNNING when this
  1699 + * routine returns.
  1700 + *
  1701 + * Returns 0 when the timer has expired otherwise -EINTR
  1702 + */
  1703 +int __sched schedule_hrtimeout(ktime_t *expires,
  1704 + const enum hrtimer_mode mode)
  1705 +{
  1706 + struct hrtimer_sleeper t;
  1707 +
  1708 + /*
  1709 + * Optimize when a zero timeout value is given. It does not
  1710 + * matter whether this is an absolute or a relative time.
  1711 + */
  1712 + if (expires && !expires->tv64) {
  1713 + __set_current_state(TASK_RUNNING);
  1714 + return 0;
  1715 + }
  1716 +
  1717 + /*
  1718 + * A NULL parameter means "inifinte"
  1719 + */
  1720 + if (!expires) {
  1721 + schedule();
  1722 + __set_current_state(TASK_RUNNING);
  1723 + return -EINTR;
  1724 + }
  1725 +
  1726 + hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
  1727 + t.timer.expires = *expires;
  1728 +
  1729 + hrtimer_init_sleeper(&t, current);
  1730 +
  1731 + hrtimer_start(&t.timer, t.timer.expires, mode);
  1732 + if (!hrtimer_active(&t.timer))
  1733 + t.task = NULL;
  1734 +
  1735 + if (likely(t.task))
  1736 + schedule();
  1737 +
  1738 + hrtimer_cancel(&t.timer);
  1739 + destroy_hrtimer_on_stack(&t.timer);
  1740 +
  1741 + __set_current_state(TASK_RUNNING);
  1742 +
  1743 + return !t.task ? 0 : -EINTR;
  1744 +}
  1745 +EXPORT_SYMBOL_GPL(schedule_hrtimeout);