aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-08-31 11:05:58 -0400
committerArjan van de Ven <arjan@linux.intel.com>2008-09-06 00:34:53 -0400
commit7bb67439bf6bd3782f07f1d7be1e63406453d5de (patch)
tree6fed7b163d96067794b6d704f5d3a35b89a167b4
parent70bb08962ea9bd50797ae9f16b2493f5f7c65053 (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>
-rw-r--r--include/linux/hrtimer.h2
-rw-r--r--kernel/hrtimer.c65
2 files changed, 67 insertions, 0 deletions
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 6d93dce61cbb..becd17db1a1a 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -346,6 +346,8 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block);
346extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, 346extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl,
347 struct task_struct *tsk); 347 struct task_struct *tsk);
348 348
349extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode);
350
349/* Soft interrupt function to run the hrtimer queues: */ 351/* Soft interrupt function to run the hrtimer queues: */
350extern void hrtimer_run_queues(void); 352extern void hrtimer_run_queues(void);
351extern void hrtimer_run_pending(void); 353extern void hrtimer_run_pending(void);
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 */
1703int __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}
1745EXPORT_SYMBOL_GPL(schedule_hrtimeout);