|
@@ -330,6 +330,92 @@ do { \
|
|
|
__ret; \
|
|
|
})
|
|
|
|
|
|
+#define __wait_event_hrtimeout(wq, condition, timeout, state) \
|
|
|
+({ \
|
|
|
+ int __ret = 0; \
|
|
|
+ DEFINE_WAIT(__wait); \
|
|
|
+ struct hrtimer_sleeper __t; \
|
|
|
+ \
|
|
|
+ hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC, \
|
|
|
+ HRTIMER_MODE_REL); \
|
|
|
+ hrtimer_init_sleeper(&__t, current); \
|
|
|
+ if ((timeout).tv64 != KTIME_MAX) \
|
|
|
+ hrtimer_start_range_ns(&__t.timer, timeout, \
|
|
|
+ current->timer_slack_ns, \
|
|
|
+ HRTIMER_MODE_REL); \
|
|
|
+ \
|
|
|
+ for (;;) { \
|
|
|
+ prepare_to_wait(&wq, &__wait, state); \
|
|
|
+ if (condition) \
|
|
|
+ break; \
|
|
|
+ if (state == TASK_INTERRUPTIBLE && \
|
|
|
+ signal_pending(current)) { \
|
|
|
+ __ret = -ERESTARTSYS; \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ if (!__t.task) { \
|
|
|
+ __ret = -ETIME; \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ schedule(); \
|
|
|
+ } \
|
|
|
+ \
|
|
|
+ hrtimer_cancel(&__t.timer); \
|
|
|
+ destroy_hrtimer_on_stack(&__t.timer); \
|
|
|
+ finish_wait(&wq, &__wait); \
|
|
|
+ __ret; \
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * wait_event_hrtimeout - sleep until a condition gets true or a timeout elapses
|
|
|
+ * @wq: the waitqueue to wait on
|
|
|
+ * @condition: a C expression for the event to wait for
|
|
|
+ * @timeout: timeout, as a ktime_t
|
|
|
+ *
|
|
|
+ * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
|
|
|
+ * @condition evaluates to true or a signal is received.
|
|
|
+ * The @condition is checked each time the waitqueue @wq is woken up.
|
|
|
+ *
|
|
|
+ * wake_up() has to be called after changing any variable that could
|
|
|
+ * change the result of the wait condition.
|
|
|
+ *
|
|
|
+ * The function returns 0 if @condition became true, or -ETIME if the timeout
|
|
|
+ * elapsed.
|
|
|
+ */
|
|
|
+#define wait_event_hrtimeout(wq, condition, timeout) \
|
|
|
+({ \
|
|
|
+ int __ret = 0; \
|
|
|
+ if (!(condition)) \
|
|
|
+ __ret = __wait_event_hrtimeout(wq, condition, timeout, \
|
|
|
+ TASK_UNINTERRUPTIBLE); \
|
|
|
+ __ret; \
|
|
|
+})
|
|
|
+
|
|
|
+/**
|
|
|
+ * wait_event_interruptible_hrtimeout - sleep until a condition gets true or a timeout elapses
|
|
|
+ * @wq: the waitqueue to wait on
|
|
|
+ * @condition: a C expression for the event to wait for
|
|
|
+ * @timeout: timeout, as a ktime_t
|
|
|
+ *
|
|
|
+ * The process is put to sleep (TASK_INTERRUPTIBLE) until the
|
|
|
+ * @condition evaluates to true or a signal is received.
|
|
|
+ * The @condition is checked each time the waitqueue @wq is woken up.
|
|
|
+ *
|
|
|
+ * wake_up() has to be called after changing any variable that could
|
|
|
+ * change the result of the wait condition.
|
|
|
+ *
|
|
|
+ * The function returns 0 if @condition became true, -ERESTARTSYS if it was
|
|
|
+ * interrupted by a signal, or -ETIME if the timeout elapsed.
|
|
|
+ */
|
|
|
+#define wait_event_interruptible_hrtimeout(wq, condition, timeout) \
|
|
|
+({ \
|
|
|
+ long __ret = 0; \
|
|
|
+ if (!(condition)) \
|
|
|
+ __ret = __wait_event_hrtimeout(wq, condition, timeout, \
|
|
|
+ TASK_INTERRUPTIBLE); \
|
|
|
+ __ret; \
|
|
|
+})
|
|
|
+
|
|
|
#define __wait_event_interruptible_exclusive(wq, condition, ret) \
|
|
|
do { \
|
|
|
DEFINE_WAIT(__wait); \
|