• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * Copyright (c) 2017 Mark Johnston <markj@FreeBSD.org>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice unmodified, this list of conditions, and the following
14  *    disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $FreeBSD: releng/12.2/sys/compat/linuxkpi/common/include/linux/wait.h 364674 2020-08-24 13:19:16Z manu $
31  */
32 
33 #ifndef _LINUX_WAIT_H_
34 #define	_LINUX_WAIT_H_
35 
36 #include <linux/spinlock.h>
37 #include "los_event.h"
38 #include "los_sys.h"
39 
40 #ifdef __cplusplus
41 #if __cplusplus
42 extern "C" {
43 #endif /* __cplusplus */
44 #endif /* __cplusplus */
45 
46 /**
47  * Notice about wait_queue_head_t:
48  * 1.The stEvent is used for task-synchronization and has the same function as wait_event_head in Linux.
49  *   In LiteOS, when wait_event is called, if the condition is not true, the task will be blocked and
50  *   mounted on stEvent.stEventList. In Linux, the blocked task will be mounted on wait_queue_head.task_list.
51  * 2.The lock and poll_queue are only used for poll operation: poll_queue is used to link poll_wait_node,
52  *   and lock is used to protect this poll_queue.
53  */
54 typedef struct wait_queue_head {
55     EVENT_CB_S     stEvent;
56     spinlock_t     lock;
57     LOS_DL_LIST    poll_queue;
58 } wait_queue_head_t;
59 
60 #define osWaitForever     0xFFFFFFFF
61 #define INVALID_ADDR      0xFFFFFFFF
62 #define DECLARE_WAIT_QUEUE_HEAD(wq) \
63         wait_queue_head_t wq = { { 0, { (struct LOS_DL_LIST *)0xFFFFFFFF, (struct LOS_DL_LIST *)0xFFFFFFFF } },	\
64         SPIN_LOCK_INITIALIZER("wait_queue_spinlock"),			\
65         { &wq.poll_queue, &wq.poll_queue } }
66 
67 void __wake_up_interruptible(wait_queue_head_t *wait);
68 void __init_waitqueue_head(wait_queue_head_t *wait);
69 
70 /**
71  * @ingroup  wait
72  * @brief Initialize the waitqueue head.
73  *
74  * @par Description:
75  * This API is used to initialize the waitqueue head.
76  *
77  * @attention
78  * <ul>
79  * <li>Please make sure the input parameter wait is valid, otherwise, the system would be crash.</li>
80  * </ul>
81  *
82  * @param  wait [IN]  struct of the process that registered on the wait queue .
83  *
84  * @retval None.
85  * @par Dependency:
86  * <ul><li>Wait.h: the header file that contains the API declaration.</li></ul>
87  * @see none
88  */
89 #define init_waitqueue_head(wait) __init_waitqueue_head(wait)
90 
91 /**
92  * @ingroup  wait
93  * @brief wakeup the process that registered on the wait queue.
94  *
95  * @par Description:
96  * This API is used to wakeup the process that registered on the wait queue.
97  *
98  * @attention
99  * <ul>
100  * <li>Please make sure the input parameter wait is valid, otherwise, the system would be crash.</li>
101  * </ul>
102  *
103  * @param  wait [IN]  struct of the process that registered on the wait queue .
104  *
105  * @retval None.
106  * @par Dependency:
107  * <ul><li>Wait.h: the header file that contains the API declaration.</li></ul>
108  * @see none
109  */
110 #define wake_up_interruptible(wait) __wake_up_interruptible(wait)
111 #define wake_up_interruptible_poll(wait, key) __wake_up_interruptible_poll(wait, key)
112 
113 /**
114  * @ingroup  wait
115  * @brief wakeup the process that registered on the wait queue.
116  *
117  * @par Description:
118  * This API is used to wakeup the process that registered on the wait queue.
119  *
120  * @attention
121  * <ul>
122  * <li>Please look up the function __wake_up_interruptible(wait).</li>
123  * </ul>
124  *
125  * @param None.
126  *
127  * @retval None.
128  * @par Dependency:
129  * <ul><li>Wait.h: the header file that contains the API declaration.</li></ul>
130  * @see wake_up_interruptible
131  */
132 #define wake_up        wake_up_interruptible
133 
134 /**
135  * @ingroup wait
136  * @brief sleep until a condition gets true.
137  *
138  * @par Description:
139  * This API is used to sleep  a process until the condition evaluates to true.
140  * The condition is checked each time when the waitqueue wait is woken up.
141  *
142  * @attention
143  * <ul>
144  * <li>none.</li>
145  * </ul>
146  *
147  * @param  wait [IN] the waitqueue to wait on.
148  * @param  condition [IN] a condition evaluates to true or false.
149 
150  * @retval #0 always return 0
151 
152  * @par Dependency:
153  * <ul><li>linux\wait.h: the header file that contains the API declaration.</li></ul>
154  * @see
155  */
156 #define wait_event(wait, condition) ({                                                                     \
157     INT32 ret = 0;                                                                                         \
158                                                                                                            \
159     if ((wait).stEvent.stEventList.pstPrev == (struct LOS_DL_LIST *)INVALID_ADDR) {                        \
160         (VOID)LOS_EventInit(&(wait).stEvent);                                                              \
161     }                                                                                                      \
162     while (!(condition)) {                                                                                 \
163         (VOID)LOS_EventRead(&(wait).stEvent, 0x1U, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, LOS_WAIT_FOREVER); \
164     }                                                                                                      \
165     ret;                                                                                                   \
166 })
167 
168 #define wait_event_interruptible      wait_event
169 
170 /**
171  * @ingroup wait
172  * @brief sleep until a condition gets true or a timeout elapses.
173  *
174  * @par Description:
175  * This API is used to sleep  a process until the condition evaluates to true or a timeout elapses.
176  * The condition is checked each time when the waitqueue wait is woken up.
177  *
178  * @attention
179  * <ul>
180  * <li>none.</li>
181  * </ul>
182  *
183  * @param  wait [IN] the waitqueue to wait on.
184  * @param  condition [IN] a condition evaluates to true or false.
185  * @param  timeout [IN] the max sleep time (unit : Tick). it is jiffies in linux.
186  *
187  * @retval #0 return 0 if the condition evaluated to false after the timeout elapsed
188  * @retval #1 return 1 if the condition evaluated to true after the timeout elapsed
189  * @retval #2 return 2 if the condition evaluated to true and the timeout is osWaitForever
190  *
191  * @par Dependency:
192  * <ul><li>linux\wait.h: the header file that contains the API declaration.</li></ul>
193  * @see
194  */
195 #define wait_event_interruptible_timeout(wait, condition, timeout)  ({                              \
196     INT32 tmpTimeout;                                                                               \
197     UINT32 ret = 2;                                                                                 \
198     UINT64 ticksnow;                                                                                \
199                                                                                                     \
200     if ((wait).stEvent.stEventList.pstPrev == (struct LOS_DL_LIST *)INVALID_ADDR) {                 \
201         (VOID)LOS_EventInit(&(wait).stEvent);                                                       \
202     }                                                                                               \
203     while (!(condition)) {                                                                          \
204         ticksnow = LOS_TickCountGet();                                                              \
205         ret = LOS_EventRead(&(wait).stEvent, 0x1U, LOS_WAITMODE_AND | LOS_WAITMODE_CLR, (timeout)); \
206         if ((timeout) == osWaitForever) {                                                           \
207             if (condition) {                                                                        \
208                 ret = 2;                                                                            \
209                 break;                                                                              \
210             } else {                                                                                \
211                 continue;                                                                           \
212             }                                                                                       \
213         }                                                                                           \
214         tmpTimeout = (INT32)((timeout) - (UINT32)(LOS_TickCountGet() - ticksnow));                  \
215         if (tmpTimeout <= 0) {                                                                      \
216             ret = (condition) ? 1 : 0;                                                              \
217             break;                                                                                  \
218         } else {                                                                                    \
219             if (ret == LOS_ERRNO_EVENT_READ_TIMEOUT) {                                              \
220                 if (condition) {                                                                    \
221                     ret = 1;                                                                        \
222                     break;                                                                          \
223                 } else {                                                                            \
224                     ret = 0;                                                                        \
225                     break;                                                                          \
226                 }                                                                                   \
227             } else {                                                                                \
228                 if (condition) {                                                                    \
229                     ret = 2;                                                                        \
230                     break;                                                                          \
231                 }                                                                                   \
232             }                                                                                       \
233         }                                                                                           \
234     }                                                                                               \
235     ret;                                                                                            \
236 })
237 
238 #define add_wait_queue(wait, newWait) do {} while (0)
239 #define remove_wait_queue(wait, oldWait) do {} while (0)
240 #define DECLARE_WAITQUEUE(wait, current) do {} while (0)
241 
linux_waitqueue_active(wait_queue_head_t * q)242 static inline int linux_waitqueue_active(wait_queue_head_t *q)
243 {
244     return !LOS_ListEmpty(&(q->stEvent.stEventList));
245 }
246 
247 #define	waitqueue_active(wqh)		linux_waitqueue_active(wqh)
248 
249 #ifdef __cplusplus
250 #if __cplusplus
251 }
252 #endif /* __cplusplus */
253 #endif /* __cplusplus */
254 
255 #endif /* _LINUX_WAIT_H_ */
256