diff options
-rw-r--r-- | include/linux/hrtimer.h | 2 | ||||
-rw-r--r-- | kernel/hrtimer.c | 65 |
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); | |||
346 | extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, | 346 | extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, |
347 | struct task_struct *tsk); | 347 | struct task_struct *tsk); |
348 | 348 | ||
349 | extern 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: */ |
350 | extern void hrtimer_run_queues(void); | 352 | extern void hrtimer_run_queues(void); |
351 | extern void hrtimer_run_pending(void); | 353 | extern 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 | */ | ||
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); | ||