2 * Copyright (c) 2014 François Tigeot
3 * Copyright (c) 2014 Imre Vadász
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #ifndef _LINUX_WAIT_H_
29 #define _LINUX_WAIT_H_
31 #include <sys/spinlock2.h>
32 #include <sys/param.h>
39 init_waitqueue_head(wait_queue_head_t *eq)
41 spin_init(&eq->lock, "linux_waitqueue");
44 #define wake_up(eq) wakeup_one(eq)
45 #define wake_up_all(eq) wakeup(eq)
48 * wait_event_interruptible_timeout:
49 * - The process is put to sleep until the condition evaluates to true.
50 * - The condition is checked each time the waitqueue wq is woken up.
51 * - wake_up has to be called after changing any variable that could change
52 * the result of the wait condition.
55 * - 0 if the timeout elapsed
56 * - the remaining jiffies if the condition evaluated to true before
57 * the timeout elapsed.
58 * - remaining jiffies are always at least 1
59 * - -ERESTARTSYS if interrupted by a signal (when PCATCH is set in flags)
61 #define __wait_event_common(wq, condition, timeout_jiffies, flags) \
63 int start_jiffies, elapsed_jiffies, remaining_jiffies, ret; \
64 bool timeout_expired = false; \
65 bool interrupted = false; \
68 start_jiffies = ticks; \
70 spin_lock(&wq.lock); \
75 ret = ssleep(&wq, &wq.lock, flags, \
76 "lwe", timeout_jiffies); \
77 if (ret == EINTR || ret == ERESTART) { \
81 if (ret == EWOULDBLOCK) { \
82 timeout_expired = true; \
86 spin_unlock(&wq.lock); \
88 elapsed_jiffies = ticks - start_jiffies; \
89 remaining_jiffies = timeout_jiffies - elapsed_jiffies; \
90 if (remaining_jiffies <= 0) \
91 remaining_jiffies = 1; \
93 if (timeout_expired) \
95 else if (interrupted) \
96 retval = -ERESTARTSYS; \
97 else if (timeout_jiffies > 0) \
98 retval = remaining_jiffies; \
105 #define wait_event(wq, condition) \
106 __wait_event_common(wq, condition, 0, 0)
108 #define wait_event_timeout(wq, condition, timeout) \
109 __wait_event_common(wq, condition, timeout, 0)
111 #define wait_event_interruptible(wq, condition) \
115 retval = __wait_event_common(wq, condition, 0, PCATCH); \
116 if (retval != -ERESTARTSYS) \
121 #define wait_event_interruptible_timeout(wq, condition, timeout) \
122 __wait_event_common(wq, condition, timeout, PCATCH)
124 #endif /* _LINUX_WAIT_H_ */