|
@@ -1678,3 +1678,68 @@ void __init hrtimers_init(void)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * schedule_hrtimeout - sleep until timeout
|
|
|
+ * @expires: timeout value (ktime_t)
|
|
|
+ * @mode: timer mode, HRTIMER_MODE_ABS or HRTIMER_MODE_REL
|
|
|
+ *
|
|
|
+ * Make the current task sleep until the given expiry time has
|
|
|
+ * elapsed. The routine will return immediately unless
|
|
|
+ * the current task state has been set (see set_current_state()).
|
|
|
+ *
|
|
|
+ * You can set the task state as follows -
|
|
|
+ *
|
|
|
+ * %TASK_UNINTERRUPTIBLE - at least @timeout time is guaranteed to
|
|
|
+ * pass before the routine returns.
|
|
|
+ *
|
|
|
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
|
|
|
+ * delivered to the current task.
|
|
|
+ *
|
|
|
+ * The current task state is guaranteed to be TASK_RUNNING when this
|
|
|
+ * routine returns.
|
|
|
+ *
|
|
|
+ * Returns 0 when the timer has expired otherwise -EINTR
|
|
|
+ */
|
|
|
+int __sched schedule_hrtimeout(ktime_t *expires,
|
|
|
+ const enum hrtimer_mode mode)
|
|
|
+{
|
|
|
+ struct hrtimer_sleeper t;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Optimize when a zero timeout value is given. It does not
|
|
|
+ * matter whether this is an absolute or a relative time.
|
|
|
+ */
|
|
|
+ if (expires && !expires->tv64) {
|
|
|
+ __set_current_state(TASK_RUNNING);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * A NULL parameter means "inifinte"
|
|
|
+ */
|
|
|
+ if (!expires) {
|
|
|
+ schedule();
|
|
|
+ __set_current_state(TASK_RUNNING);
|
|
|
+ return -EINTR;
|
|
|
+ }
|
|
|
+
|
|
|
+ hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, mode);
|
|
|
+ t.timer.expires = *expires;
|
|
|
+
|
|
|
+ hrtimer_init_sleeper(&t, current);
|
|
|
+
|
|
|
+ hrtimer_start(&t.timer, t.timer.expires, mode);
|
|
|
+ if (!hrtimer_active(&t.timer))
|
|
|
+ t.task = NULL;
|
|
|
+
|
|
|
+ if (likely(t.task))
|
|
|
+ schedule();
|
|
|
+
|
|
|
+ hrtimer_cancel(&t.timer);
|
|
|
+ destroy_hrtimer_on_stack(&t.timer);
|
|
|
+
|
|
|
+ __set_current_state(TASK_RUNNING);
|
|
|
+
|
|
|
+ return !t.task ? 0 : -EINTR;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL_GPL(schedule_hrtimeout);
|