Commit 7bb67439bf6bd3782f07f1d7be1e63406453d5de
1 parent
70bb08962e
Exists in
master
and in
4 other branches
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); |
kernel/hrtimer.c
... | ... | @@ -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); |