Grid Community Toolkit
6.2.1567772254 (tag: v6.2.20190906)
gsi_openssh
source
openbsd-compat
sys-queue.h
1
/* $OpenBSD: queue.h,v 1.36 2012/04/11 13:29:14 naddy 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
/* OPENBSD ORIGINAL: sys/sys/queue.h */
36
37
#ifndef _FAKE_QUEUE_H_
38
#define _FAKE_QUEUE_H_
39
40
/*
41
* Require for OS/X and other platforms that have old/broken/incomplete
42
* <sys/queue.h>.
43
*/
44
#undef SLIST_HEAD
45
#undef SLIST_HEAD_INITIALIZER
46
#undef SLIST_ENTRY
47
#undef SLIST_FOREACH_PREVPTR
48
#undef SLIST_FIRST
49
#undef SLIST_END
50
#undef SLIST_EMPTY
51
#undef SLIST_NEXT
52
#undef SLIST_FOREACH
53
#undef SLIST_INIT
54
#undef SLIST_INSERT_AFTER
55
#undef SLIST_INSERT_HEAD
56
#undef SLIST_REMOVE_HEAD
57
#undef SLIST_REMOVE
58
#undef SLIST_REMOVE_NEXT
59
#undef LIST_HEAD
60
#undef LIST_HEAD_INITIALIZER
61
#undef LIST_ENTRY
62
#undef LIST_FIRST
63
#undef LIST_END
64
#undef LIST_EMPTY
65
#undef LIST_NEXT
66
#undef LIST_FOREACH
67
#undef LIST_INIT
68
#undef LIST_INSERT_AFTER
69
#undef LIST_INSERT_BEFORE
70
#undef LIST_INSERT_HEAD
71
#undef LIST_REMOVE
72
#undef LIST_REPLACE
73
#undef SIMPLEQ_HEAD
74
#undef SIMPLEQ_HEAD_INITIALIZER
75
#undef SIMPLEQ_ENTRY
76
#undef SIMPLEQ_FIRST
77
#undef SIMPLEQ_END
78
#undef SIMPLEQ_EMPTY
79
#undef SIMPLEQ_NEXT
80
#undef SIMPLEQ_FOREACH
81
#undef SIMPLEQ_INIT
82
#undef SIMPLEQ_INSERT_HEAD
83
#undef SIMPLEQ_INSERT_TAIL
84
#undef SIMPLEQ_INSERT_AFTER
85
#undef SIMPLEQ_REMOVE_HEAD
86
#undef TAILQ_HEAD
87
#undef TAILQ_HEAD_INITIALIZER
88
#undef TAILQ_ENTRY
89
#undef TAILQ_FIRST
90
#undef TAILQ_END
91
#undef TAILQ_NEXT
92
#undef TAILQ_LAST
93
#undef TAILQ_PREV
94
#undef TAILQ_EMPTY
95
#undef TAILQ_FOREACH
96
#undef TAILQ_FOREACH_REVERSE
97
#undef TAILQ_INIT
98
#undef TAILQ_INSERT_HEAD
99
#undef TAILQ_INSERT_TAIL
100
#undef TAILQ_INSERT_AFTER
101
#undef TAILQ_INSERT_BEFORE
102
#undef TAILQ_REMOVE
103
#undef TAILQ_REPLACE
104
#undef CIRCLEQ_HEAD
105
#undef CIRCLEQ_HEAD_INITIALIZER
106
#undef CIRCLEQ_ENTRY
107
#undef CIRCLEQ_FIRST
108
#undef CIRCLEQ_LAST
109
#undef CIRCLEQ_END
110
#undef CIRCLEQ_NEXT
111
#undef CIRCLEQ_PREV
112
#undef CIRCLEQ_EMPTY
113
#undef CIRCLEQ_FOREACH
114
#undef CIRCLEQ_FOREACH_REVERSE
115
#undef CIRCLEQ_INIT
116
#undef CIRCLEQ_INSERT_AFTER
117
#undef CIRCLEQ_INSERT_BEFORE
118
#undef CIRCLEQ_INSERT_HEAD
119
#undef CIRCLEQ_INSERT_TAIL
120
#undef CIRCLEQ_REMOVE
121
#undef CIRCLEQ_REPLACE
122
123
/*
124
* This file defines five types of data structures: singly-linked lists,
125
* lists, simple queues, tail queues, and circular queues.
126
*
127
*
128
* A singly-linked list is headed by a single forward pointer. The elements
129
* are singly linked for minimum space and pointer manipulation overhead at
130
* the expense of O(n) removal for arbitrary elements. New elements can be
131
* added to the list after an existing element or at the head of the list.
132
* Elements being removed from the head of the list should use the explicit
133
* macro for this purpose for optimum efficiency. A singly-linked list may
134
* only be traversed in the forward direction. Singly-linked lists are ideal
135
* for applications with large datasets and few or no removals or for
136
* implementing a LIFO queue.
137
*
138
* A list is headed by a single forward pointer (or an array of forward
139
* pointers for a hash table header). The elements are doubly linked
140
* so that an arbitrary element can be removed without a need to
141
* traverse the list. New elements can be added to the list before
142
* or after an existing element or at the head of the list. A list
143
* may only be traversed in the forward direction.
144
*
145
* A simple queue is headed by a pair of pointers, one the head of the
146
* list and the other to the tail of the list. The elements are singly
147
* linked to save space, so elements can only be removed from the
148
* head of the list. New elements can be added to the list before or after
149
* an existing element, at the head of the list, or at the end of the
150
* list. A simple queue may only be traversed in the forward direction.
151
*
152
* A tail queue is headed by a pair of pointers, one to the head of the
153
* list and the other to the tail of the list. The elements are doubly
154
* linked so that an arbitrary element can be removed without a need to
155
* traverse the list. New elements can be added to the list before or
156
* after an existing element, at the head of the list, or at the end of
157
* the list. A tail queue may be traversed in either direction.
158
*
159
* A circle queue is headed by a pair of pointers, one to the head of the
160
* list and the other to the tail of the list. The elements are doubly
161
* linked so that an arbitrary element can be removed without a need to
162
* traverse the list. New elements can be added to the list before or after
163
* an existing element, at the head of the list, or at the end of the list.
164
* A circle queue may be traversed in either direction, but has a more
165
* complex end of list detection.
166
*
167
* For details on the use of these macros, see the queue(3) manual page.
168
*/
169
170
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
171
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
172
#else
173
#define _Q_INVALIDATE(a)
174
#endif
175
176
/*
177
* Singly-linked List definitions.
178
*/
179
#define SLIST_HEAD(name, type) \
180
struct name { \
181
struct type *slh_first;
/* first element */
\
182
}
183
184
#define SLIST_HEAD_INITIALIZER(head) \
185
{ NULL }
186
187
#define SLIST_ENTRY(type) \
188
struct { \
189
struct type *sle_next;
/* next element */
\
190
}
191
192
/*
193
* Singly-linked List access methods.
194
*/
195
#define SLIST_FIRST(head) ((head)->slh_first)
196
#define SLIST_END(head) NULL
197
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
198
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
199
200
#define SLIST_FOREACH(var, head, field) \
201
for((var) = SLIST_FIRST(head); \
202
(var) != SLIST_END(head); \
203
(var) = SLIST_NEXT(var, field))
204
205
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
206
for ((var) = SLIST_FIRST(head); \
207
(var) && ((tvar) = SLIST_NEXT(var, field), 1); \
208
(var) = (tvar))
209
210
/*
211
* Singly-linked List functions.
212
*/
213
#define SLIST_INIT(head) { \
214
SLIST_FIRST(head) = SLIST_END(head); \
215
}
216
217
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
218
(elm)->field.sle_next = (slistelm)->field.sle_next; \
219
(slistelm)->field.sle_next = (elm); \
220
} while (0)
221
222
#define SLIST_INSERT_HEAD(head, elm, field) do { \
223
(elm)->field.sle_next = (head)->slh_first; \
224
(head)->slh_first = (elm); \
225
} while (0)
226
227
#define SLIST_REMOVE_AFTER(elm, field) do { \
228
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
229
} while (0)
230
231
#define SLIST_REMOVE_HEAD(head, field) do { \
232
(head)->slh_first = (head)->slh_first->field.sle_next; \
233
} while (0)
234
235
#define SLIST_REMOVE(head, elm, type, field) do { \
236
if ((head)->slh_first == (elm)) { \
237
SLIST_REMOVE_HEAD((head), field); \
238
} else { \
239
struct type *curelm = (head)->slh_first; \
240
\
241
while (curelm->field.sle_next != (elm)) \
242
curelm = curelm->field.sle_next; \
243
curelm->field.sle_next = \
244
curelm->field.sle_next->field.sle_next; \
245
_Q_INVALIDATE((elm)->field.sle_next); \
246
} \
247
} while (0)
248
249
/*
250
* List definitions.
251
*/
252
#define LIST_HEAD(name, type) \
253
struct name { \
254
struct type *lh_first;
/* first element */
\
255
}
256
257
#define LIST_HEAD_INITIALIZER(head) \
258
{ NULL }
259
260
#define LIST_ENTRY(type) \
261
struct { \
262
struct type *le_next;
/* next element */
\
263
struct type **le_prev;
/* address of previous next element */
\
264
}
265
266
/*
267
* List access methods
268
*/
269
#define LIST_FIRST(head) ((head)->lh_first)
270
#define LIST_END(head) NULL
271
#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
272
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
273
274
#define LIST_FOREACH(var, head, field) \
275
for((var) = LIST_FIRST(head); \
276
(var)!= LIST_END(head); \
277
(var) = LIST_NEXT(var, field))
278
279
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
280
for ((var) = LIST_FIRST(head); \
281
(var) && ((tvar) = LIST_NEXT(var, field), 1); \
282
(var) = (tvar))
283
284
/*
285
* List functions.
286
*/
287
#define LIST_INIT(head) do { \
288
LIST_FIRST(head) = LIST_END(head); \
289
} while (0)
290
291
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
292
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
293
(listelm)->field.le_next->field.le_prev = \
294
&(elm)->field.le_next; \
295
(listelm)->field.le_next = (elm); \
296
(elm)->field.le_prev = &(listelm)->field.le_next; \
297
} while (0)
298
299
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
300
(elm)->field.le_prev = (listelm)->field.le_prev; \
301
(elm)->field.le_next = (listelm); \
302
*(listelm)->field.le_prev = (elm); \
303
(listelm)->field.le_prev = &(elm)->field.le_next; \
304
} while (0)
305
306
#define LIST_INSERT_HEAD(head, elm, field) do { \
307
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
308
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
309
(head)->lh_first = (elm); \
310
(elm)->field.le_prev = &(head)->lh_first; \
311
} while (0)
312
313
#define LIST_REMOVE(elm, field) do { \
314
if ((elm)->field.le_next != NULL) \
315
(elm)->field.le_next->field.le_prev = \
316
(elm)->field.le_prev; \
317
*(elm)->field.le_prev = (elm)->field.le_next; \
318
_Q_INVALIDATE((elm)->field.le_prev); \
319
_Q_INVALIDATE((elm)->field.le_next); \
320
} while (0)
321
322
#define LIST_REPLACE(elm, elm2, field) do { \
323
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
324
(elm2)->field.le_next->field.le_prev = \
325
&(elm2)->field.le_next; \
326
(elm2)->field.le_prev = (elm)->field.le_prev; \
327
*(elm2)->field.le_prev = (elm2); \
328
_Q_INVALIDATE((elm)->field.le_prev); \
329
_Q_INVALIDATE((elm)->field.le_next); \
330
} while (0)
331
332
/*
333
* Simple queue definitions.
334
*/
335
#define SIMPLEQ_HEAD(name, type) \
336
struct name { \
337
struct type *sqh_first;
/* first element */
\
338
struct type **sqh_last;
/* addr of last next element */
\
339
}
340
341
#define SIMPLEQ_HEAD_INITIALIZER(head) \
342
{ NULL, &(head).sqh_first }
343
344
#define SIMPLEQ_ENTRY(type) \
345
struct { \
346
struct type *sqe_next;
/* next element */
\
347
}
348
349
/*
350
* Simple queue access methods.
351
*/
352
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
353
#define SIMPLEQ_END(head) NULL
354
#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
355
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
356
357
#define SIMPLEQ_FOREACH(var, head, field) \
358
for((var) = SIMPLEQ_FIRST(head); \
359
(var) != SIMPLEQ_END(head); \
360
(var) = SIMPLEQ_NEXT(var, field))
361
362
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
363
for ((var) = SIMPLEQ_FIRST(head); \
364
(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
365
(var) = (tvar))
366
367
/*
368
* Simple queue functions.
369
*/
370
#define SIMPLEQ_INIT(head) do { \
371
(head)->sqh_first = NULL; \
372
(head)->sqh_last = &(head)->sqh_first; \
373
} while (0)
374
375
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
376
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
377
(head)->sqh_last = &(elm)->field.sqe_next; \
378
(head)->sqh_first = (elm); \
379
} while (0)
380
381
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
382
(elm)->field.sqe_next = NULL; \
383
*(head)->sqh_last = (elm); \
384
(head)->sqh_last = &(elm)->field.sqe_next; \
385
} while (0)
386
387
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
388
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
389
(head)->sqh_last = &(elm)->field.sqe_next; \
390
(listelm)->field.sqe_next = (elm); \
391
} while (0)
392
393
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
394
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
395
(head)->sqh_last = &(head)->sqh_first; \
396
} while (0)
397
398
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
399
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
400
== NULL) \
401
(head)->sqh_last = &(elm)->field.sqe_next; \
402
} while (0)
403
404
/*
405
* Tail queue definitions.
406
*/
407
#define TAILQ_HEAD(name, type) \
408
struct name { \
409
struct type *tqh_first;
/* first element */
\
410
struct type **tqh_last;
/* addr of last next element */
\
411
}
412
413
#define TAILQ_HEAD_INITIALIZER(head) \
414
{ NULL, &(head).tqh_first }
415
416
#define TAILQ_ENTRY(type) \
417
struct { \
418
struct type *tqe_next;
/* next element */
\
419
struct type **tqe_prev;
/* address of previous next element */
\
420
}
421
422
/*
423
* tail queue access methods
424
*/
425
#define TAILQ_FIRST(head) ((head)->tqh_first)
426
#define TAILQ_END(head) NULL
427
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
428
#define TAILQ_LAST(head, headname) \
429
(*(((struct headname *)((head)->tqh_last))->tqh_last))
430
/* XXX */
431
#define TAILQ_PREV(elm, headname, field) \
432
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
433
#define TAILQ_EMPTY(head) \
434
(TAILQ_FIRST(head) == TAILQ_END(head))
435
436
#define TAILQ_FOREACH(var, head, field) \
437
for((var) = TAILQ_FIRST(head); \
438
(var) != TAILQ_END(head); \
439
(var) = TAILQ_NEXT(var, field))
440
441
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
442
for ((var) = TAILQ_FIRST(head); \
443
(var) != TAILQ_END(head) && \
444
((tvar) = TAILQ_NEXT(var, field), 1); \
445
(var) = (tvar))
446
447
448
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
449
for((var) = TAILQ_LAST(head, headname); \
450
(var) != TAILQ_END(head); \
451
(var) = TAILQ_PREV(var, headname, field))
452
453
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
454
for ((var) = TAILQ_LAST(head, headname); \
455
(var) != TAILQ_END(head) && \
456
((tvar) = TAILQ_PREV(var, headname, field), 1); \
457
(var) = (tvar))
458
459
/*
460
* Tail queue functions.
461
*/
462
#define TAILQ_INIT(head) do { \
463
(head)->tqh_first = NULL; \
464
(head)->tqh_last = &(head)->tqh_first; \
465
} while (0)
466
467
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
468
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
469
(head)->tqh_first->field.tqe_prev = \
470
&(elm)->field.tqe_next; \
471
else \
472
(head)->tqh_last = &(elm)->field.tqe_next; \
473
(head)->tqh_first = (elm); \
474
(elm)->field.tqe_prev = &(head)->tqh_first; \
475
} while (0)
476
477
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
478
(elm)->field.tqe_next = NULL; \
479
(elm)->field.tqe_prev = (head)->tqh_last; \
480
*(head)->tqh_last = (elm); \
481
(head)->tqh_last = &(elm)->field.tqe_next; \
482
} while (0)
483
484
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
485
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
486
(elm)->field.tqe_next->field.tqe_prev = \
487
&(elm)->field.tqe_next; \
488
else \
489
(head)->tqh_last = &(elm)->field.tqe_next; \
490
(listelm)->field.tqe_next = (elm); \
491
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
492
} while (0)
493
494
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
495
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
496
(elm)->field.tqe_next = (listelm); \
497
*(listelm)->field.tqe_prev = (elm); \
498
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
499
} while (0)
500
501
#define TAILQ_REMOVE(head, elm, field) do { \
502
if (((elm)->field.tqe_next) != NULL) \
503
(elm)->field.tqe_next->field.tqe_prev = \
504
(elm)->field.tqe_prev; \
505
else \
506
(head)->tqh_last = (elm)->field.tqe_prev; \
507
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
508
_Q_INVALIDATE((elm)->field.tqe_prev); \
509
_Q_INVALIDATE((elm)->field.tqe_next); \
510
} while (0)
511
512
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
513
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
514
(elm2)->field.tqe_next->field.tqe_prev = \
515
&(elm2)->field.tqe_next; \
516
else \
517
(head)->tqh_last = &(elm2)->field.tqe_next; \
518
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
519
*(elm2)->field.tqe_prev = (elm2); \
520
_Q_INVALIDATE((elm)->field.tqe_prev); \
521
_Q_INVALIDATE((elm)->field.tqe_next); \
522
} while (0)
523
524
/*
525
* Circular queue definitions.
526
*/
527
#define CIRCLEQ_HEAD(name, type) \
528
struct name { \
529
struct type *cqh_first;
/* first element */
\
530
struct type *cqh_last;
/* last element */
\
531
}
532
533
#define CIRCLEQ_HEAD_INITIALIZER(head) \
534
{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
535
536
#define CIRCLEQ_ENTRY(type) \
537
struct { \
538
struct type *cqe_next;
/* next element */
\
539
struct type *cqe_prev;
/* previous element */
\
540
}
541
542
/*
543
* Circular queue access methods
544
*/
545
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
546
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
547
#define CIRCLEQ_END(head) ((void *)(head))
548
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
549
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
550
#define CIRCLEQ_EMPTY(head) \
551
(CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
552
553
#define CIRCLEQ_FOREACH(var, head, field) \
554
for((var) = CIRCLEQ_FIRST(head); \
555
(var) != CIRCLEQ_END(head); \
556
(var) = CIRCLEQ_NEXT(var, field))
557
558
#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
559
for ((var) = CIRCLEQ_FIRST(head); \
560
(var) != CIRCLEQ_END(head) && \
561
((tvar) = CIRCLEQ_NEXT(var, field), 1); \
562
(var) = (tvar))
563
564
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
565
for((var) = CIRCLEQ_LAST(head); \
566
(var) != CIRCLEQ_END(head); \
567
(var) = CIRCLEQ_PREV(var, field))
568
569
#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
570
for ((var) = CIRCLEQ_LAST(head, headname); \
571
(var) != CIRCLEQ_END(head) && \
572
((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
573
(var) = (tvar))
574
575
/*
576
* Circular queue functions.
577
*/
578
#define CIRCLEQ_INIT(head) do { \
579
(head)->cqh_first = CIRCLEQ_END(head); \
580
(head)->cqh_last = CIRCLEQ_END(head); \
581
} while (0)
582
583
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
584
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
585
(elm)->field.cqe_prev = (listelm); \
586
if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
587
(head)->cqh_last = (elm); \
588
else \
589
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
590
(listelm)->field.cqe_next = (elm); \
591
} while (0)
592
593
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
594
(elm)->field.cqe_next = (listelm); \
595
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
596
if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
597
(head)->cqh_first = (elm); \
598
else \
599
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
600
(listelm)->field.cqe_prev = (elm); \
601
} while (0)
602
603
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
604
(elm)->field.cqe_next = (head)->cqh_first; \
605
(elm)->field.cqe_prev = CIRCLEQ_END(head); \
606
if ((head)->cqh_last == CIRCLEQ_END(head)) \
607
(head)->cqh_last = (elm); \
608
else \
609
(head)->cqh_first->field.cqe_prev = (elm); \
610
(head)->cqh_first = (elm); \
611
} while (0)
612
613
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
614
(elm)->field.cqe_next = CIRCLEQ_END(head); \
615
(elm)->field.cqe_prev = (head)->cqh_last; \
616
if ((head)->cqh_first == CIRCLEQ_END(head)) \
617
(head)->cqh_first = (elm); \
618
else \
619
(head)->cqh_last->field.cqe_next = (elm); \
620
(head)->cqh_last = (elm); \
621
} while (0)
622
623
#define CIRCLEQ_REMOVE(head, elm, field) do { \
624
if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
625
(head)->cqh_last = (elm)->field.cqe_prev; \
626
else \
627
(elm)->field.cqe_next->field.cqe_prev = \
628
(elm)->field.cqe_prev; \
629
if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
630
(head)->cqh_first = (elm)->field.cqe_next; \
631
else \
632
(elm)->field.cqe_prev->field.cqe_next = \
633
(elm)->field.cqe_next; \
634
_Q_INVALIDATE((elm)->field.cqe_prev); \
635
_Q_INVALIDATE((elm)->field.cqe_next); \
636
} while (0)
637
638
#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
639
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
640
CIRCLEQ_END(head)) \
641
(head).cqh_last = (elm2); \
642
else \
643
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
644
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
645
CIRCLEQ_END(head)) \
646
(head).cqh_first = (elm2); \
647
else \
648
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
649
_Q_INVALIDATE((elm)->field.cqe_prev); \
650
_Q_INVALIDATE((elm)->field.cqe_next); \
651
} while (0)
652
653
#endif
/* !_FAKE_QUEUE_H_ */
Generated by
1.8.15