diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2008-08-31 11:05:58 -0400 |
---|---|---|
committer | Arjan van de Ven <arjan@linux.intel.com> | 2008-09-06 00:34:53 -0400 |
commit | 7bb67439bf6bd3782f07f1d7be1e63406453d5de (patch) | |
tree | 6fed7b163d96067794b6d704f5d3a35b89a167b4 /kernel/hrtimer.c | |
parent | 70bb08962ea9bd50797ae9f16b2493f5f7c65053 (diff) |
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>
Diffstat (limited to 'kernel/hrtimer.c')
-rw-r--r-- | kernel/hrtimer.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index b8e4dce80a74..782137dc755f 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -1678,3 +1678,68 @@ void __init hrtimers_init(void) | |||
1678 | #endif | 1678 | #endif |
1679 | } | 1679 | } |
1680 | 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); | ||