open62541
1.3.12
Open source implementation of OPC UA
Loading...
Searching...
No Matches
doc
open62541
deps
open62541_queue.h
Go to the documentation of this file.
1
/* $OpenBSD: queue.h,v 1.38 2013/07/03 15:05:21 fgsch Exp $ */
2
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
3
4
/*
5
* Copyright (c) 1991, 1993
6
* The Regents of the University of California. 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, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. Neither the name of the University nor the names of its contributors
17
* may be used to endorse or promote products derived from this software
18
* without specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
* SUCH DAMAGE.
31
*
32
* @(#)queue.h 8.5 (Berkeley) 8/20/94
33
*/
34
35
#ifndef _SYS_QUEUE_H_
36
#define _SYS_QUEUE_H_
37
38
/*
39
* This file defines five types of data structures: singly-linked lists,
40
* lists, simple queues, tail queues, and circular queues.
41
*
42
*
43
* A singly-linked list is headed by a single forward pointer. The elements
44
* are singly linked for minimum space and pointer manipulation overhead at
45
* the expense of O(n) removal for arbitrary elements. New elements can be
46
* added to the list after an existing element or at the head of the list.
47
* Elements being removed from the head of the list should use the explicit
48
* macro for this purpose for optimum efficiency. A singly-linked list may
49
* only be traversed in the forward direction. Singly-linked lists are ideal
50
* for applications with large datasets and few or no removals or for
51
* implementing a LIFO queue.
52
*
53
* A list is headed by a single forward pointer (or an array of forward
54
* pointers for a hash table header). The elements are doubly linked
55
* so that an arbitrary element can be removed without a need to
56
* traverse the list. New elements can be added to the list before
57
* or after an existing element or at the head of the list. A list
58
* may only be traversed in the forward direction.
59
*
60
* A simple queue is headed by a pair of pointers, one the head of the
61
* list and the other to the tail of the list. The elements are singly
62
* linked to save space, so elements can only be removed from the
63
* head of the list. New elements can be added to the list before or after
64
* an existing element, at the head of the list, or at the end of the
65
* list. A simple queue may only be traversed in the forward direction.
66
*
67
* A tail queue is headed by a pair of pointers, one to the head of the
68
* list and the other to the tail of the list. The elements are doubly
69
* linked so that an arbitrary element can be removed without a need to
70
* traverse the list. New elements can be added to the list before or
71
* after an existing element, at the head of the list, or at the end of
72
* the list. A tail queue may be traversed in either direction.
73
*
74
* A circle queue is headed by a pair of pointers, one to the head of the
75
* list and the other to the tail of the list. The elements are doubly
76
* linked so that an arbitrary element can be removed without a need to
77
* traverse the list. New elements can be added to the list before or after
78
* an existing element, at the head of the list, or at the end of the list.
79
* A circle queue may be traversed in either direction, but has a more
80
* complex end of list detection.
81
*
82
* For details on the use of these macros, see the queue(3) manual page.
83
*/
84
85
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
86
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
87
#else
88
#define _Q_INVALIDATE(a)
89
#endif
90
91
/*
92
* Singly-linked List definitions.
93
*/
94
#define SLIST_HEAD(name, type) \
95
struct name { \
96
struct type *slh_first;
/* first element */
\
97
}
98
99
#define SLIST_HEAD_INITIALIZER(head) \
100
{ NULL }
101
102
#define SLIST_ENTRY(type) \
103
struct { \
104
struct type *sle_next;
/* next element */
\
105
}
106
107
/*
108
* Singly-linked List access methods.
109
*/
110
#define SLIST_FIRST(head) ((head)->slh_first)
111
#define SLIST_END(head) NULL
112
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
113
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
114
115
#define SLIST_FOREACH(var, head, field) \
116
for((var) = SLIST_FIRST(head); \
117
(var) != SLIST_END(head); \
118
(var) = SLIST_NEXT(var, field))
119
120
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
121
for ((var) = SLIST_FIRST(head); \
122
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
123
(var) = (tvar))
124
125
/*
126
* Singly-linked List functions.
127
*/
128
#define SLIST_INIT(head) do { \
129
SLIST_FIRST(head) = SLIST_END(head); \
130
} while(0)
131
132
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
133
(elm)->field.sle_next = (slistelm)->field.sle_next; \
134
(slistelm)->field.sle_next = (elm); \
135
} while (0)
136
137
#define SLIST_INSERT_HEAD(head, elm, field) do { \
138
(elm)->field.sle_next = (head)->slh_first; \
139
(head)->slh_first = (elm); \
140
} while (0)
141
142
#define SLIST_REMOVE_AFTER(elm, field) do { \
143
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
144
} while (0)
145
146
#define SLIST_REMOVE_HEAD(head, field) do { \
147
(head)->slh_first = (head)->slh_first->field.sle_next; \
148
} while (0)
149
150
#define SLIST_REMOVE(head, elm, type, field) do { \
151
if ((head)->slh_first == (elm)) { \
152
SLIST_REMOVE_HEAD((head), field); \
153
} else { \
154
struct type *curelm = (head)->slh_first; \
155
\
156
while (curelm->field.sle_next != (elm)) \
157
curelm = curelm->field.sle_next; \
158
curelm->field.sle_next = \
159
curelm->field.sle_next->field.sle_next; \
160
_Q_INVALIDATE((elm)->field.sle_next); \
161
} \
162
} while (0)
163
164
/*
165
* List definitions.
166
*/
167
#define LIST_HEAD(name, type) \
168
struct name { \
169
struct type *lh_first;
/* first element */
\
170
}
171
172
#define LIST_HEAD_INITIALIZER(head) \
173
{ NULL }
174
175
#define LIST_ENTRY(type) \
176
struct { \
177
struct type *le_next;
/* next element */
\
178
struct type **le_prev;
/* address of previous next element */
\
179
}
180
181
/*
182
* List access methods
183
*/
184
#define LIST_FIRST(head) ((head)->lh_first)
185
#define LIST_END(head) NULL
186
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
187
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
188
189
#define LIST_FOREACH(var, head, field) \
190
for((var) = LIST_FIRST(head); \
191
(var)!= LIST_END(head); \
192
(var) = LIST_NEXT(var, field))
193
194
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
195
for ((var) = LIST_FIRST(head); \
196
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
197
(var) = (tvar))
198
199
/*
200
* List functions.
201
*/
202
#define LIST_INIT(head) do { \
203
LIST_FIRST(head) = LIST_END(head); \
204
} while (0)
205
206
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
207
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
208
(listelm)->field.le_next->field.le_prev = \
209
&(elm)->field.le_next; \
210
(listelm)->field.le_next = (elm); \
211
(elm)->field.le_prev = &(listelm)->field.le_next; \
212
} while (0)
213
214
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
215
(elm)->field.le_prev = (listelm)->field.le_prev; \
216
(elm)->field.le_next = (listelm); \
217
*(listelm)->field.le_prev = (elm); \
218
(listelm)->field.le_prev = &(elm)->field.le_next; \
219
} while (0)
220
221
#define LIST_INSERT_HEAD(head, elm, field) do { \
222
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
223
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
224
(head)->lh_first = (elm); \
225
(elm)->field.le_prev = &(head)->lh_first; \
226
} while (0)
227
228
#define LIST_REMOVE(elm, field) do { \
229
if ((elm)->field.le_next != NULL) \
230
(elm)->field.le_next->field.le_prev = \
231
(elm)->field.le_prev; \
232
*(elm)->field.le_prev = (elm)->field.le_next; \
233
_Q_INVALIDATE((elm)->field.le_prev); \
234
_Q_INVALIDATE((elm)->field.le_next); \
235
} while (0)
236
237
#define LIST_REPLACE(elm, elm2, field) do { \
238
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
239
(elm2)->field.le_next->field.le_prev = \
240
&(elm2)->field.le_next; \
241
(elm2)->field.le_prev = (elm)->field.le_prev; \
242
*(elm2)->field.le_prev = (elm2); \
243
_Q_INVALIDATE((elm)->field.le_prev); \
244
_Q_INVALIDATE((elm)->field.le_next); \
245
} while (0)
246
247
/*
248
* Simple queue definitions.
249
*/
250
#define SIMPLEQ_HEAD(name, type) \
251
struct name { \
252
struct type *sqh_first;
/* first element */
\
253
struct type **sqh_last;
/* addr of last next element */
\
254
}
255
256
#define SIMPLEQ_HEAD_INITIALIZER(head) \
257
{ NULL, &(head).sqh_first }
258
259
#define SIMPLEQ_ENTRY(type) \
260
struct { \
261
struct type *sqe_next;
/* next element */
\
262
}
263
264
/*
265
* Simple queue access methods.
266
*/
267
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
268
#define SIMPLEQ_END(head) NULL
269
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
270
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
271
272
#define SIMPLEQ_FOREACH(var, head, field) \
273
for((var) = SIMPLEQ_FIRST(head); \
274
(var) != SIMPLEQ_END(head); \
275
(var) = SIMPLEQ_NEXT(var, field))
276
277
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
278
for ((var) = SIMPLEQ_FIRST(head); \
279
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
280
(var) = (tvar))
281
282
/*
283
* Simple queue functions.
284
*/
285
#define SIMPLEQ_INIT(head) do { \
286
(head)->sqh_first = NULL; \
287
(head)->sqh_last = &(head)->sqh_first; \
288
} while (0)
289
290
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
291
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
292
(head)->sqh_last = &(elm)->field.sqe_next; \
293
(head)->sqh_first = (elm); \
294
} while (0)
295
296
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
297
(elm)->field.sqe_next = NULL; \
298
*(head)->sqh_last = (elm); \
299
(head)->sqh_last = &(elm)->field.sqe_next; \
300
} while (0)
301
302
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
303
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
304
(head)->sqh_last = &(elm)->field.sqe_next; \
305
(listelm)->field.sqe_next = (elm); \
306
} while (0)
307
308
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
309
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
310
(head)->sqh_last = &(head)->sqh_first; \
311
} while (0)
312
313
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
314
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
315
== NULL) \
316
(head)->sqh_last = &(elm)->field.sqe_next; \
317
} while (0)
318
319
/*
320
* XOR Simple queue definitions.
321
*/
322
#define XSIMPLEQ_HEAD(name, type) \
323
struct name { \
324
struct type *sqx_first;
/* first element */
\
325
struct type **sqx_last;
/* addr of last next element */
\
326
unsigned long sqx_cookie; \
327
}
328
329
#define XSIMPLEQ_ENTRY(type) \
330
struct { \
331
struct type *sqx_next;
/* next element */
\
332
}
333
334
/*
335
* XOR Simple queue access methods.
336
*/
337
#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \
338
(unsigned long)(ptr)))
339
#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))
340
#define XSIMPLEQ_END(head) NULL
341
#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
342
#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
343
344
345
#define XSIMPLEQ_FOREACH(var, head, field) \
346
for ((var) = XSIMPLEQ_FIRST(head); \
347
(var) != XSIMPLEQ_END(head); \
348
(var) = XSIMPLEQ_NEXT(head, var, field))
349
350
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
351
for ((var) = XSIMPLEQ_FIRST(head); \
352
(var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
353
(var) = (tvar))
354
355
/*
356
* XOR Simple queue functions.
357
*/
358
#define XSIMPLEQ_INIT(head) do { \
359
arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
360
(head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \
361
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
362
} while (0)
363
364
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \
365
if (((elm)->field.sqx_next = (head)->sqx_first) == \
366
XSIMPLEQ_XOR(head, NULL)) \
367
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
368
(head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \
369
} while (0)
370
371
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \
372
(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \
373
*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
374
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
375
} while (0)
376
377
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
378
if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \
379
XSIMPLEQ_XOR(head, NULL)) \
380
(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
381
(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \
382
} while (0)
383
384
#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \
385
if (((head)->sqx_first = XSIMPLEQ_XOR(head, \
386
(head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
387
(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
388
} while (0)
389
390
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
391
if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \
392
(elm)->field.sqx_next)->field.sqx_next) \
393
== XSIMPLEQ_XOR(head, NULL)) \
394
(head)->sqx_last = \
395
XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
396
} while (0)
397
398
399
/*
400
* Tail queue definitions.
401
*/
402
#define TAILQ_HEAD(name, type) \
403
struct name { \
404
struct type *tqh_first;
/* first element */
\
405
struct type **tqh_last;
/* addr of last next element */
\
406
}
407
408
#define TAILQ_HEAD_INITIALIZER(head) \
409
{ NULL, &(head).tqh_first }
410
411
#define TAILQ_ENTRY(type) \
412
struct { \
413
struct type *tqe_next;
/* next element */
\
414
struct type **tqe_prev;
/* address of previous next element */
\
415
}
416
417
/**
418
* tail queue access methods
419
*/
420
#define TAILQ_FIRST(head) ((head)->tqh_first)
421
#define TAILQ_END(head) NULL
422
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
423
#define TAILQ_LAST(head, headname) \
424
(*(((struct headname *)((head)->tqh_last))->tqh_last))
425
/** XXX */
426
#define TAILQ_PREV(elm, headname, field) \
427
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
428
#define TAILQ_EMPTY(head) \
429
(TAILQ_FIRST(head) == TAILQ_END(head))
430
431
#define TAILQ_FOREACH(var, head, field) \
432
for((var) = TAILQ_FIRST(head); \
433
(var) != TAILQ_END(head); \
434
(var) = TAILQ_NEXT(var, field))
435
436
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
437
for ((var) = TAILQ_FIRST(head); \
438
(var) != TAILQ_END(head) && \
439
((tvar) = TAILQ_NEXT(var, field), 1); \
440
(var) = (tvar))
441
442
443
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
444
for((var) = TAILQ_LAST(head, headname); \
445
(var) != TAILQ_END(head); \
446
(var) = TAILQ_PREV(var, headname, field))
447
448
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
449
for ((var) = TAILQ_LAST(head, headname); \
450
(var) != TAILQ_END(head) && \
451
((tvar) = TAILQ_PREV(var, headname, field), 1); \
452
(var) = (tvar))
453
454
/*
455
* Tail queue functions.
456
*/
457
#define TAILQ_INIT(head) do { \
458
(head)->tqh_first = NULL; \
459
(head)->tqh_last = &(head)->tqh_first; \
460
} while (0)
461
462
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
463
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
464
(head)->tqh_first->field.tqe_prev = \
465
&(elm)->field.tqe_next; \
466
else \
467
(head)->tqh_last = &(elm)->field.tqe_next; \
468
(head)->tqh_first = (elm); \
469
(elm)->field.tqe_prev = &(head)->tqh_first; \
470
} while (0)
471
472
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
473
(elm)->field.tqe_next = NULL; \
474
(elm)->field.tqe_prev = (head)->tqh_last; \
475
*(head)->tqh_last = (elm); \
476
(head)->tqh_last = &(elm)->field.tqe_next; \
477
} while (0)
478
479
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
480
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
481
(elm)->field.tqe_next->field.tqe_prev = \
482
&(elm)->field.tqe_next; \
483
else \
484
(head)->tqh_last = &(elm)->field.tqe_next; \
485
(listelm)->field.tqe_next = (elm); \
486
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
487
} while (0)
488
489
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
490
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
491
(elm)->field.tqe_next = (listelm); \
492
*(listelm)->field.tqe_prev = (elm); \
493
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
494
} while (0)
495
496
#define TAILQ_REMOVE(head, elm, field) do { \
497
if (((elm)->field.tqe_next) != NULL) \
498
(elm)->field.tqe_next->field.tqe_prev = \
499
(elm)->field.tqe_prev; \
500
else \
501
(head)->tqh_last = (elm)->field.tqe_prev; \
502
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
503
_Q_INVALIDATE((elm)->field.tqe_prev); \
504
_Q_INVALIDATE((elm)->field.tqe_next); \
505
} while (0)
506
507
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
508
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
509
(elm2)->field.tqe_next->field.tqe_prev = \
510
&(elm2)->field.tqe_next; \
511
else \
512
(head)->tqh_last = &(elm2)->field.tqe_next; \
513
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
514
*(elm2)->field.tqe_prev = (elm2); \
515
_Q_INVALIDATE((elm)->field.tqe_prev); \
516
_Q_INVALIDATE((elm)->field.tqe_next); \
517
} while (0)
518
519
/*
520
* Circular queue definitions.
521
*/
522
#define CIRCLEQ_HEAD(name, type) \
523
struct name { \
524
struct type *cqh_first;
/* first element */
\
525
struct type *cqh_last;
/* last element */
\
526
}
527
528
#define CIRCLEQ_HEAD_INITIALIZER(head) \
529
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
530
531
#define CIRCLEQ_ENTRY(type) \
532
struct { \
533
struct type *cqe_next;
/* next element */
\
534
struct type *cqe_prev;
/* previous element */
\
535
}
536
537
/*
538
* Circular queue access methods
539
*/
540
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
541
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
542
#define CIRCLEQ_END(head) ((void *)(head))
543
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
544
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
545
#define CIRCLEQ_EMPTY(head) \
546
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
547
548
#define CIRCLEQ_FOREACH(var, head, field) \
549
for((var) = CIRCLEQ_FIRST(head); \
550
(var) != CIRCLEQ_END(head); \
551
(var) = CIRCLEQ_NEXT(var, field))
552
553
#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
554
for ((var) = CIRCLEQ_FIRST(head); \
555
(var) != CIRCLEQ_END(head) && \
556
((tvar) = CIRCLEQ_NEXT(var, field), 1); \
557
(var) = (tvar))
558
559
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
560
for((var) = CIRCLEQ_LAST(head); \
561
(var) != CIRCLEQ_END(head); \
562
(var) = CIRCLEQ_PREV(var, field))
563
564
#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
565
for ((var) = CIRCLEQ_LAST(head, headname); \
566
(var) != CIRCLEQ_END(head) && \
567
((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
568
(var) = (tvar))
569
570
/*
571
* Circular queue functions.
572
*/
573
#define CIRCLEQ_INIT(head) do { \
574
(head)->cqh_first = CIRCLEQ_END(head); \
575
(head)->cqh_last = CIRCLEQ_END(head); \
576
} while (0)
577
578
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
579
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
580
(elm)->field.cqe_prev = (listelm); \
581
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
582
(head)->cqh_last = (elm); \
583
else \
584
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
585
(listelm)->field.cqe_next = (elm); \
586
} while (0)
587
588
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
589
(elm)->field.cqe_next = (listelm); \
590
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
591
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
592
(head)->cqh_first = (elm); \
593
else \
594
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
595
(listelm)->field.cqe_prev = (elm); \
596
} while (0)
597
598
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
599
(elm)->field.cqe_next = (head)->cqh_first; \
600
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
601
if ((head)->cqh_last == CIRCLEQ_END(head)) \
602
(head)->cqh_last = (elm); \
603
else \
604
(head)->cqh_first->field.cqe_prev = (elm); \
605
(head)->cqh_first = (elm); \
606
} while (0)
607
608
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
609
(elm)->field.cqe_next = CIRCLEQ_END(head); \
610
(elm)->field.cqe_prev = (head)->cqh_last; \
611
if ((head)->cqh_first == CIRCLEQ_END(head)) \
612
(head)->cqh_first = (elm); \
613
else \
614
(head)->cqh_last->field.cqe_next = (elm); \
615
(head)->cqh_last = (elm); \
616
} while (0)
617
618
#define CIRCLEQ_REMOVE(head, elm, field) do { \
619
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
620
(head)->cqh_last = (elm)->field.cqe_prev; \
621
else \
622
(elm)->field.cqe_next->field.cqe_prev = \
623
(elm)->field.cqe_prev; \
624
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
625
(head)->cqh_first = (elm)->field.cqe_next; \
626
else \
627
(elm)->field.cqe_prev->field.cqe_next = \
628
(elm)->field.cqe_next; \
629
_Q_INVALIDATE((elm)->field.cqe_prev); \
630
_Q_INVALIDATE((elm)->field.cqe_next); \
631
} while (0)
632
633
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
634
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
635
CIRCLEQ_END(head)) \
636
(head)->cqh_last = (elm2); \
637
else \
638
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
639
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
640
CIRCLEQ_END(head)) \
641
(head)->cqh_first = (elm2); \
642
else \
643
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
644
_Q_INVALIDATE((elm)->field.cqe_prev); \
645
_Q_INVALIDATE((elm)->field.cqe_next); \
646
} while (0)
647
648
#endif
/* !_SYS_QUEUE_H_ */
Generated by
1.11.0