]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/compat/linuxkpi/common/include/linux/wait.h
Add proper error checking for the string to number conversion
[FreeBSD/FreeBSD.git] / sys / compat / linuxkpi / common / include / linux / wait.h
1 /*-
2  * Copyright (c) 2010 Isilon Systems, Inc.
3  * Copyright (c) 2010 iX Systems, Inc.
4  * Copyright (c) 2010 Panasas, Inc.
5  * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice unmodified, this list of conditions, and the following
13  *    disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 #ifndef _LINUX_WAIT_H_
32 #define _LINUX_WAIT_H_
33
34 #include <linux/compiler.h>
35 #include <linux/list.h>
36 #include <linux/jiffies.h>
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/sleepqueue.h>
41 #include <sys/kernel.h>
42 #include <sys/proc.h>
43
44 typedef struct {
45 } wait_queue_t;
46
47 typedef struct {
48         unsigned int    wchan;
49 } wait_queue_head_t;
50
51 #define init_waitqueue_head(x) \
52     do { } while (0)
53
54 static inline void
55 __wake_up(wait_queue_head_t *q, int all)
56 {
57         int wakeup_swapper;
58         void *c;
59
60         c = &q->wchan;
61         sleepq_lock(c);
62         if (all)
63                 wakeup_swapper = sleepq_broadcast(c, SLEEPQ_SLEEP, 0, 0);
64         else
65                 wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0);
66         sleepq_release(c);
67         if (wakeup_swapper)
68                 kick_proc0();
69 }
70
71 #define wake_up(q)                              __wake_up(q, 0)
72 #define wake_up_nr(q, nr)                       __wake_up(q, 1)
73 #define wake_up_all(q)                          __wake_up(q, 1)
74 #define wake_up_interruptible(q)                __wake_up(q, 0)
75 #define wake_up_interruptible_nr(q, nr)         __wake_up(q, 1)
76 #define wake_up_interruptible_all(q, nr)        __wake_up(q, 1)
77
78 #define wait_event(q, cond)                                             \
79 do {                                                                    \
80         void *c = &(q).wchan;                                           \
81         if (!(cond)) {                                                  \
82                 for (;;) {                                              \
83                         if (SCHEDULER_STOPPED())                        \
84                                 break;                                  \
85                         sleepq_lock(c);                                 \
86                         if (cond) {                                     \
87                                 sleepq_release(c);                      \
88                                 break;                                  \
89                         }                                               \
90                         sleepq_add(c, NULL, "completion", SLEEPQ_SLEEP, 0); \
91                         sleepq_wait(c, 0);                              \
92                 }                                                       \
93         }                                                               \
94 } while (0)
95
96 #define wait_event_interruptible(q, cond)                               \
97 ({                                                                      \
98         void *c = &(q).wchan;                                           \
99         int _error;                                                     \
100                                                                         \
101         _error = 0;                                                     \
102         if (!(cond)) {                                                  \
103                 for (; _error == 0;) {                                  \
104                         if (SCHEDULER_STOPPED())                        \
105                                 break;                                  \
106                         sleepq_lock(c);                                 \
107                         if (cond) {                                     \
108                                 sleepq_release(c);                      \
109                                 break;                                  \
110                         }                                               \
111                         sleepq_add(c, NULL, "completion",               \
112                             SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0);    \
113                         if (sleepq_wait_sig(c, 0))                      \
114                                 _error = -ERESTARTSYS;                  \
115                 }                                                       \
116         }                                                               \
117         -_error;                                                        \
118 })
119
120 #define wait_event_interruptible_timeout(q, cond, timeout)              \
121 ({                                                                      \
122         void *c = &(q).wchan;                                           \
123         long end = jiffies + timeout;                                   \
124         int __ret = 0;                                                  \
125         int __rc = 0;                                                   \
126                                                                         \
127         if (!(cond)) {                                                  \
128                 for (; __rc == 0;) {                                    \
129                         if (SCHEDULER_STOPPED())                        \
130                                 break;                                  \
131                         sleepq_lock(c);                                 \
132                         if (cond) {                                     \
133                                 sleepq_release(c);                      \
134                                 __ret = 1;                              \
135                                 break;                                  \
136                         }                                               \
137                         sleepq_add(c, NULL, "completion",               \
138                         SLEEPQ_SLEEP | SLEEPQ_INTERRUPTIBLE, 0);        \
139                         sleepq_set_timeout(c, linux_timer_jiffies_until(end));\
140                         __rc = sleepq_timedwait_sig (c, 0);             \
141                         if (__rc != 0) {                                \
142                                 /* check for timeout or signal.         \
143                                  * 0 if the condition evaluated to false\
144                                  * after the timeout elapsed,  1 if the \
145                                  * condition evaluated to true after the\
146                                  * timeout elapsed.                     \
147                                  */                                     \
148                                 if (__rc == EWOULDBLOCK)                \
149                                         __ret = (cond);                 \
150                                  else                                   \
151                                         __ret = -ERESTARTSYS;           \
152                         }                                               \
153                                                                         \
154                 }                                                       \
155         } else {                                                        \
156                 /* return remaining jiffies (at least 1) if the         \
157                  * condition evaluated to true before the timeout       \
158                  * elapsed.                                             \
159                  */                                                     \
160                 __ret = (end - jiffies);                                \
161                 if( __ret < 1 )                                         \
162                         __ret = 1;                                      \
163         }                                                               \
164         __ret;                                                          \
165 })
166
167
168 static inline int
169 waitqueue_active(wait_queue_head_t *q)
170 {
171         return 0;       /* XXX: not really implemented */
172 }
173
174 #define DEFINE_WAIT(name)       \
175         wait_queue_t name = {}
176
177 static inline void
178 prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
179 {
180 }
181
182 static inline void
183 finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
184 {
185 }
186
187 #endif  /* _LINUX_WAIT_H_ */