ESP8266_RTOS_SDK  v1.4.0
queue.h
1 /*
2  * ESPRSSIF MIT License
3  *
4  * Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
5  *
6  * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
7  * it is free of charge, to any person obtaining a copy of this software and associated
8  * documentation files (the "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
11  * to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or
14  * substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #ifndef _SYS_QUEUE_H_
26 #define _SYS_QUEUE_H_
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #define QMD_SAVELINK(name, link)
33 #define TRASHIT(x)
34 
35 /*
36  * Singly-linked List declarations.
37  */
38 #define SLIST_HEAD(name, type) \
39  struct name { \
40  struct type *slh_first; /* first element */ \
41  }
42 
43 #define SLIST_HEAD_INITIALIZER(head) \
44  { NULL }
45 
46 #define SLIST_ENTRY(type) \
47  struct { \
48  struct type *sle_next; /* next element */ \
49  }
50 
51 /*
52  * Singly-linked List functions.
53  */
54 #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
55 
56 #define SLIST_FIRST(head) ((head)->slh_first)
57 
58 #define SLIST_FOREACH(var, head, field) \
59  for ((var) = SLIST_FIRST((head)); \
60  (var); \
61  (var) = SLIST_NEXT((var), field))
62 
63 #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
64  for ((var) = SLIST_FIRST((head)); \
65  (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
66  (var) = (tvar))
67 
68 #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
69  for ((varp) = &SLIST_FIRST((head)); \
70  ((var) = *(varp)) != NULL; \
71  (varp) = &SLIST_NEXT((var), field))
72 
73 #define SLIST_INIT(head) do { \
74  SLIST_FIRST((head)) = NULL; \
75  } while (0)
76 
77 #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
78  SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
79  SLIST_NEXT((slistelm), field) = (elm); \
80  } while (0)
81 
82 #define SLIST_INSERT_HEAD(head, elm, field) do { \
83  SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
84  SLIST_FIRST((head)) = (elm); \
85  } while (0)
86 
87 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
88 
89 #define SLIST_REMOVE(head, elm, type, field) do { \
90  QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
91  if (SLIST_FIRST((head)) == (elm)) { \
92  SLIST_REMOVE_HEAD((head), field); \
93  } \
94  else { \
95  struct type *curelm = SLIST_FIRST((head)); \
96  while (SLIST_NEXT(curelm, field) != (elm)) \
97  curelm = SLIST_NEXT(curelm, field); \
98  SLIST_REMOVE_AFTER(curelm, field); \
99  } \
100  TRASHIT(*oldnext); \
101  } while (0)
102 
103 #define SLIST_REMOVE_AFTER(elm, field) do { \
104  SLIST_NEXT(elm, field) = \
105  SLIST_NEXT(SLIST_NEXT(elm, field), field); \
106  } while (0)
107 
108 #define SLIST_REMOVE_HEAD(head, field) do { \
109  SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
110  } while (0)
111 
112 /*
113  * Singly-linked Tail queue declarations.
114  */
115 #define STAILQ_HEAD(name, type) \
116  struct name { \
117  struct type *stqh_first; /* first element */ \
118  struct type **stqh_last; /* addr of last next element */ \
119  }
120 
121 #define STAILQ_HEAD_INITIALIZER(head) \
122  { NULL, &(head).stqh_first }
123 
124 #define STAILQ_ENTRY(type) \
125  struct { \
126  struct type *stqe_next; /* next element */ \
127  }
128 
129 /*
130  * Singly-linked Tail queue functions.
131  */
132 #define STAILQ_CONCAT(head1, head2) do { \
133  if (!STAILQ_EMPTY((head2))) { \
134  *(head1)->stqh_last = (head2)->stqh_first; \
135  (head1)->stqh_last = (head2)->stqh_last; \
136  STAILQ_INIT((head2)); \
137  } \
138  } while (0)
139 
140 #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
141 
142 #define STAILQ_FIRST(head) ((head)->stqh_first)
143 
144 #define STAILQ_FOREACH(var, head, field) \
145  for((var) = STAILQ_FIRST((head)); \
146  (var); \
147  (var) = STAILQ_NEXT((var), field))
148 
149 
150 #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
151  for ((var) = STAILQ_FIRST((head)); \
152  (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
153  (var) = (tvar))
154 
155 #define STAILQ_INIT(head) do { \
156  STAILQ_FIRST((head)) = NULL; \
157  (head)->stqh_last = &STAILQ_FIRST((head)); \
158  } while (0)
159 
160 #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
161  if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
162  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
163  STAILQ_NEXT((tqelm), field) = (elm); \
164  } while (0)
165 
166 #define STAILQ_INSERT_HEAD(head, elm, field) do { \
167  if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
168  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
169  STAILQ_FIRST((head)) = (elm); \
170  } while (0)
171 
172 #define STAILQ_INSERT_TAIL(head, elm, field) do { \
173  STAILQ_NEXT((elm), field) = NULL; \
174  *(head)->stqh_last = (elm); \
175  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
176  } while (0)
177 
178 #define STAILQ_LAST(head, type, field) \
179  (STAILQ_EMPTY((head))? \
180  NULL : \
181  ((struct type *)(void *)\
182  ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
183 
184 #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
185 
186 #define STAILQ_REMOVE(head, elm, type, field) do { \
187  QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
188  if (STAILQ_FIRST((head)) == (elm)) { \
189  STAILQ_REMOVE_HEAD((head), field); \
190  } \
191  else { \
192  struct type *curelm = STAILQ_FIRST((head)); \
193  while (STAILQ_NEXT(curelm, field) != (elm)) \
194  curelm = STAILQ_NEXT(curelm, field); \
195  STAILQ_REMOVE_AFTER(head, curelm, field); \
196  } \
197  TRASHIT(*oldnext); \
198  } while (0)
199 
200 #define STAILQ_REMOVE_HEAD(head, field) do { \
201  if ((STAILQ_FIRST((head)) = \
202  STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
203  (head)->stqh_last = &STAILQ_FIRST((head)); \
204  } while (0)
205 
206 #define STAILQ_REMOVE_AFTER(head, elm, field) do { \
207  if ((STAILQ_NEXT(elm, field) = \
208  STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
209  (head)->stqh_last = &STAILQ_NEXT((elm), field); \
210  } while (0)
211 
212 #define STAILQ_SWAP(head1, head2, type) do { \
213  struct type *swap_first = STAILQ_FIRST(head1); \
214  struct type **swap_last = (head1)->stqh_last; \
215  STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
216  (head1)->stqh_last = (head2)->stqh_last; \
217  STAILQ_FIRST(head2) = swap_first; \
218  (head2)->stqh_last = swap_last; \
219  if (STAILQ_EMPTY(head1)) \
220  (head1)->stqh_last = &STAILQ_FIRST(head1); \
221  if (STAILQ_EMPTY(head2)) \
222  (head2)->stqh_last = &STAILQ_FIRST(head2); \
223  } while (0)
224 
225 #define STAILQ_INSERT_CHAIN_HEAD(head, elm_chead, elm_ctail, field) do { \
226  if ((STAILQ_NEXT(elm_ctail, field) = STAILQ_FIRST(head)) == NULL ) { \
227  (head)->stqh_last = &STAILQ_NEXT(elm_ctail, field); \
228  } \
229  STAILQ_FIRST(head) = (elm_chead); \
230  } while (0)
231 
232 #ifdef __cplusplus
233 }
234 #endif
235 
236 #endif /* !_SYS_QUEUE_H_ */