ESP8266_RTOS_SDK v1.4.0

- Main Page
- Modules
- Data Structures
- Files

- File List

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_ */