Coverage Report

Created: 2025-11-11 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/compat/queue.h
Line
Count
Source
1
/*  $OpenBSD: queue.h,v 1.44 2016/09/09 20:31:46 millert 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 _COMPAT_QUEUE_H_
36
#define _COMPAT_QUEUE_H_
37
38
/*
39
 * This file defines five types of data structures: singly-linked lists,
40
 * lists, simple queues, tail queues and XOR simple 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 to 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
 * An XOR simple queue is used in the same way as a regular simple queue.
75
 * The difference is that the head structure also includes a "cookie" that
76
 * is XOR'd with the queue pointer (first, last or next) to generate the
77
 * real pointer value.
78
 *
79
 * For details on the use of these macros, see the queue(3) manual page.
80
 */
81
82
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
83
#define _Q_INVALIDATE(a) (a) = ((void *)-1)
84
#else
85
#define _Q_INVALIDATE(a)
86
#endif
87
88
/*
89
 * Singly-linked List definitions.
90
 */
91
#define SLIST_HEAD(name, type)            \
92
struct name {               \
93
  struct type *slh_first; /* first element */     \
94
}
95
96
#define SLIST_HEAD_INITIALIZER(head)          \
97
  { NULL }
98
99
#define SLIST_ENTRY(type)           \
100
struct {                \
101
  struct type *sle_next;  /* next element */      \
102
}
103
104
/*
105
 * Singly-linked List access methods.
106
 */
107
#define SLIST_FIRST(head) ((head)->slh_first)
108
#define SLIST_END(head)   NULL
109
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
110
#define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
111
112
#define SLIST_FOREACH(var, head, field)         \
113
  for((var) = SLIST_FIRST(head);          \
114
      (var) != SLIST_END(head);         \
115
      (var) = SLIST_NEXT(var, field))
116
117
#define SLIST_FOREACH_SAFE(var, head, field, tvar)      \
118
  for ((var) = SLIST_FIRST(head);       \
119
      (var) && ((tvar) = SLIST_NEXT(var, field), 1);    \
120
      (var) = (tvar))
121
122
/*
123
 * Singly-linked List functions.
124
 */
125
#define SLIST_INIT(head) {            \
126
  SLIST_FIRST(head) = SLIST_END(head);        \
127
}
128
129
#define SLIST_INSERT_AFTER(slistelm, elm, field) do {     \
130
  (elm)->field.sle_next = (slistelm)->field.sle_next;   \
131
  (slistelm)->field.sle_next = (elm);       \
132
} while (0)
133
134
#define SLIST_INSERT_HEAD(head, elm, field) do {      \
135
  (elm)->field.sle_next = (head)->slh_first;      \
136
  (head)->slh_first = (elm);          \
137
} while (0)
138
139
#define SLIST_REMOVE_AFTER(elm, field) do {       \
140
  (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next;  \
141
} while (0)
142
143
#define SLIST_REMOVE_HEAD(head, field) do {       \
144
  (head)->slh_first = (head)->slh_first->field.sle_next;    \
145
} while (0)
146
147
#define SLIST_REMOVE(head, elm, type, field) do {     \
148
  if ((head)->slh_first == (elm)) {       \
149
    SLIST_REMOVE_HEAD((head), field);     \
150
  } else {              \
151
    struct type *curelm = (head)->slh_first;    \
152
                  \
153
    while (curelm->field.sle_next != (elm))     \
154
      curelm = curelm->field.sle_next;    \
155
    curelm->field.sle_next =        \
156
        curelm->field.sle_next->field.sle_next;   \
157
  }               \
158
  _Q_INVALIDATE((elm)->field.sle_next);       \
159
} while (0)
160
161
/*
162
 * List definitions.
163
 */
164
#define LIST_HEAD(name, type)           \
165
struct name {               \
166
  struct type *lh_first;  /* first element */     \
167
}
168
169
#define LIST_HEAD_INITIALIZER(head)         \
170
  { NULL }
171
172
#define LIST_ENTRY(type)            \
173
struct {                \
174
  struct type *le_next; /* next element */      \
175
  struct type **le_prev;  /* address of previous next element */  \
176
}
177
178
/*
179
 * List access methods.
180
 */
181
0
#define LIST_FIRST(head)    ((head)->lh_first)
182
0
#define LIST_END(head)      NULL
183
#define LIST_EMPTY(head)    (LIST_FIRST(head) == LIST_END(head))
184
0
#define LIST_NEXT(elm, field)   ((elm)->field.le_next)
185
186
#define LIST_FOREACH(var, head, field)          \
187
0
  for((var) = LIST_FIRST(head);         \
188
0
      (var)!= LIST_END(head);         \
189
0
      (var) = LIST_NEXT(var, field))
190
191
#define LIST_FOREACH_SAFE(var, head, field, tvar)     \
192
  for ((var) = LIST_FIRST(head);        \
193
      (var) && ((tvar) = LIST_NEXT(var, field), 1);   \
194
      (var) = (tvar))
195
196
/*
197
 * List functions.
198
 */
199
#define LIST_INIT(head) do {            \
200
  LIST_FIRST(head) = LIST_END(head);        \
201
} while (0)
202
203
#define LIST_INSERT_AFTER(listelm, elm, field) do {     \
204
  if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)  \
205
    (listelm)->field.le_next->field.le_prev =   \
206
        &(elm)->field.le_next;        \
207
  (listelm)->field.le_next = (elm);       \
208
  (elm)->field.le_prev = &(listelm)->field.le_next;   \
209
} while (0)
210
211
#define LIST_INSERT_BEFORE(listelm, elm, field) do {      \
212
  (elm)->field.le_prev = (listelm)->field.le_prev;    \
213
  (elm)->field.le_next = (listelm);       \
214
  *(listelm)->field.le_prev = (elm);        \
215
  (listelm)->field.le_prev = &(elm)->field.le_next;   \
216
} while (0)
217
218
0
#define LIST_INSERT_HEAD(head, elm, field) do {       \
219
0
  if (((elm)->field.le_next = (head)->lh_first) != NULL)   \
220
0
    (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
221
0
  (head)->lh_first = (elm);         \
222
0
  (elm)->field.le_prev = &(head)->lh_first;     \
223
0
} while (0)
224
225
0
#define LIST_REMOVE(elm, field) do {         \
226
0
  if ((elm)->field.le_next != NULL)       \
227
0
    (elm)->field.le_next->field.le_prev =     \
228
0
        (elm)->field.le_prev;       \
229
0
  *(elm)->field.le_prev = (elm)->field.le_next;     \
230
0
  _Q_INVALIDATE((elm)->field.le_prev);        \
231
0
  _Q_INVALIDATE((elm)->field.le_next);        \
232
0
} while (0)
233
234
#define LIST_REPLACE(elm, elm2, field) do {       \
235
  if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
236
    (elm2)->field.le_next->field.le_prev =      \
237
        &(elm2)->field.le_next;       \
238
  (elm2)->field.le_prev = (elm)->field.le_prev;     \
239
  *(elm2)->field.le_prev = (elm2);        \
240
  _Q_INVALIDATE((elm)->field.le_prev);        \
241
  _Q_INVALIDATE((elm)->field.le_next);        \
242
} while (0)
243
244
/*
245
 * Simple queue definitions.
246
 */
247
#define SIMPLEQ_HEAD(name, type)          \
248
struct name {               \
249
  struct type *sqh_first; /* first element */     \
250
  struct type **sqh_last; /* addr of last next element */   \
251
}
252
253
#define SIMPLEQ_HEAD_INITIALIZER(head)          \
254
  { NULL, &(head).sqh_first }
255
256
#define SIMPLEQ_ENTRY(type)           \
257
struct {                \
258
  struct type *sqe_next;  /* next element */      \
259
}
260
261
/*
262
 * Simple queue access methods.
263
 */
264
#define SIMPLEQ_FIRST(head)     ((head)->sqh_first)
265
#define SIMPLEQ_END(head)     NULL
266
#define SIMPLEQ_EMPTY(head)     (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
267
#define SIMPLEQ_NEXT(elm, field)    ((elm)->field.sqe_next)
268
269
#define SIMPLEQ_FOREACH(var, head, field)       \
270
  for((var) = SIMPLEQ_FIRST(head);        \
271
      (var) != SIMPLEQ_END(head);         \
272
      (var) = SIMPLEQ_NEXT(var, field))
273
274
#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar)      \
275
  for ((var) = SIMPLEQ_FIRST(head);       \
276
      (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1);    \
277
      (var) = (tvar))
278
279
/*
280
 * Simple queue functions.
281
 */
282
#define SIMPLEQ_INIT(head) do {           \
283
  (head)->sqh_first = NULL;         \
284
  (head)->sqh_last = &(head)->sqh_first;        \
285
} while (0)
286
287
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do {      \
288
  if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)  \
289
    (head)->sqh_last = &(elm)->field.sqe_next;    \
290
  (head)->sqh_first = (elm);          \
291
} while (0)
292
293
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do {      \
294
  (elm)->field.sqe_next = NULL;         \
295
  *(head)->sqh_last = (elm);          \
296
  (head)->sqh_last = &(elm)->field.sqe_next;      \
297
} while (0)
298
299
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {    \
300
  if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
301
    (head)->sqh_last = &(elm)->field.sqe_next;    \
302
  (listelm)->field.sqe_next = (elm);        \
303
} while (0)
304
305
#define SIMPLEQ_REMOVE_HEAD(head, field) do {     \
306
  if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
307
    (head)->sqh_last = &(head)->sqh_first;      \
308
} while (0)
309
310
#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {     \
311
  if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
312
      == NULL)              \
313
    (head)->sqh_last = &(elm)->field.sqe_next;    \
314
} while (0)
315
316
#define SIMPLEQ_CONCAT(head1, head2) do {       \
317
  if (!SIMPLEQ_EMPTY((head2))) {          \
318
    *(head1)->sqh_last = (head2)->sqh_first;    \
319
    (head1)->sqh_last = (head2)->sqh_last;      \
320
    SIMPLEQ_INIT((head2));          \
321
  }               \
322
} while (0)
323
324
/*
325
 * XOR Simple queue definitions.
326
 */
327
#define XSIMPLEQ_HEAD(name, type)         \
328
struct name {               \
329
  struct type *sqx_first; /* first element */     \
330
  struct type **sqx_last; /* addr of last next element */   \
331
  unsigned long sqx_cookie;         \
332
}
333
334
#define XSIMPLEQ_ENTRY(type)            \
335
struct {                \
336
  struct type *sqx_next;  /* next element */      \
337
}
338
339
/*
340
 * XOR Simple queue access methods.
341
 */
342
#define XSIMPLEQ_XOR(head, ptr)     ((__typeof(ptr))((head)->sqx_cookie ^ \
343
          (unsigned long)(ptr)))
344
#define XSIMPLEQ_FIRST(head)      XSIMPLEQ_XOR(head, ((head)->sqx_first))
345
#define XSIMPLEQ_END(head)      NULL
346
#define XSIMPLEQ_EMPTY(head)      (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
347
#define XSIMPLEQ_NEXT(head, elm, field)    XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))
348
349
350
#define XSIMPLEQ_FOREACH(var, head, field)        \
351
  for ((var) = XSIMPLEQ_FIRST(head);        \
352
      (var) != XSIMPLEQ_END(head);        \
353
      (var) = XSIMPLEQ_NEXT(head, var, field))
354
355
#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar)     \
356
  for ((var) = XSIMPLEQ_FIRST(head);        \
357
      (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \
358
      (var) = (tvar))
359
360
/*
361
 * XOR Simple queue functions.
362
 */
363
#define XSIMPLEQ_INIT(head) do {          \
364
  arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \
365
  (head)->sqx_first = XSIMPLEQ_XOR(head, NULL);     \
366
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first);  \
367
} while (0)
368
369
#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do {     \
370
  if (((elm)->field.sqx_next = (head)->sqx_first) ==    \
371
      XSIMPLEQ_XOR(head, NULL))         \
372
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
373
  (head)->sqx_first = XSIMPLEQ_XOR(head, (elm));      \
374
} while (0)
375
376
#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do {     \
377
  (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL);   \
378
  *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \
379
  (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);  \
380
} while (0)
381
382
#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {   \
383
  if (((elm)->field.sqx_next = (listelm)->field.sqx_next) ==  \
384
      XSIMPLEQ_XOR(head, NULL))         \
385
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \
386
  (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm));    \
387
} while (0)
388
389
#define XSIMPLEQ_REMOVE_HEAD(head, field) do {        \
390
  if (((head)->sqx_first = XSIMPLEQ_XOR(head,     \
391
      (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \
392
    (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \
393
} while (0)
394
395
#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do {      \
396
  if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head,     \
397
      (elm)->field.sqx_next)->field.sqx_next)     \
398
      == XSIMPLEQ_XOR(head, NULL))        \
399
    (head)->sqx_last =          \
400
        XSIMPLEQ_XOR(head, &(elm)->field.sqx_next);   \
401
} while (0)
402
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
1.89M
#define TAILQ_FIRST(head)   ((head)->tqh_first)
426
3.12M
#define TAILQ_END(head)     NULL
427
39.8k
#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)
428
#define TAILQ_LAST(head, headname)          \
429
7.23k
  (*(((struct headname *)((head)->tqh_last))->tqh_last))
430
/* XXX */
431
#define TAILQ_PREV(elm, headname, field)        \
432
0
  (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
433
#define TAILQ_EMPTY(head)           \
434
517k
  (TAILQ_FIRST(head) == TAILQ_END(head))
435
436
#define TAILQ_FOREACH(var, head, field)         \
437
70.0k
  for((var) = TAILQ_FIRST(head);         \
438
64.5k
      (var) != TAILQ_END(head);         \
439
62.6k
      (var) = TAILQ_NEXT(var, field))
440
441
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)      \
442
1.24M
  for ((var) = TAILQ_FIRST(head);         \
443
1.27M
      (var) != TAILQ_END(head) &&         \
444
1.27M
      ((tvar) = TAILQ_NEXT(var, field), 1);     \
445
1.23M
      (var) = (tvar))
446
447
448
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)   \
449
0
  for((var) = TAILQ_LAST(head, headname);       \
450
0
      (var) != TAILQ_END(head);         \
451
0
      (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
601k
#define TAILQ_INIT(head) do {           \
463
589k
  (head)->tqh_first = NULL;         \
464
589k
  (head)->tqh_last = &(head)->tqh_first;        \
465
589k
} while (0)
466
467
12.3k
#define TAILQ_INSERT_HEAD(head, elm, field) do {     \
468
12.3k
  if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
469
12.3k
    (head)->tqh_first->field.tqe_prev =     \
470
253
        &(elm)->field.tqe_next;       \
471
12.3k
  else                \
472
12.3k
    (head)->tqh_last = &(elm)->field.tqe_next;   \
473
12.3k
  (head)->tqh_first = (elm);          \
474
12.3k
  (elm)->field.tqe_prev = &(head)->tqh_first;     \
475
12.3k
} while (0)
476
477
63.8k
#define TAILQ_INSERT_TAIL(head, elm, field) do {     \
478
63.8k
  (elm)->field.tqe_next = NULL;         \
479
63.8k
  (elm)->field.tqe_prev = (head)->tqh_last;     \
480
63.8k
  *(head)->tqh_last = (elm);          \
481
63.8k
  (head)->tqh_last = &(elm)->field.tqe_next;      \
482
63.8k
} while (0)
483
484
1.72k
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {   \
485
1.72k
  if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
486
1.72k
    (elm)->field.tqe_next->field.tqe_prev =     \
487
528
        &(elm)->field.tqe_next;       \
488
1.72k
  else                \
489
1.72k
    (head)->tqh_last = &(elm)->field.tqe_next;   \
490
1.72k
  (listelm)->field.tqe_next = (elm);        \
491
1.72k
  (elm)->field.tqe_prev = &(listelm)->field.tqe_next;   \
492
1.72k
} while (0)
493
494
3.02k
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do {     \
495
3.02k
  (elm)->field.tqe_prev = (listelm)->field.tqe_prev;    \
496
3.02k
  (elm)->field.tqe_next = (listelm);        \
497
3.02k
  *(listelm)->field.tqe_prev = (elm);       \
498
3.02k
  (listelm)->field.tqe_prev = &(elm)->field.tqe_next;   \
499
3.02k
} while (0)
500
501
80.5k
#define TAILQ_REMOVE(head, elm, field) do {       \
502
80.5k
  if (((elm)->field.tqe_next) != NULL)       \
503
80.5k
    (elm)->field.tqe_next->field.tqe_prev =     \
504
55.8k
        (elm)->field.tqe_prev;       \
505
80.5k
  else                \
506
80.5k
    (head)->tqh_last = (elm)->field.tqe_prev;   \
507
80.5k
  *(elm)->field.tqe_prev = (elm)->field.tqe_next;     \
508
80.5k
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
509
80.5k
  _Q_INVALIDATE((elm)->field.tqe_next);       \
510
80.5k
} while (0)
511
512
0
#define TAILQ_REPLACE(head, elm, elm2, field) do {     \
513
0
  if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
514
0
    (elm2)->field.tqe_next->field.tqe_prev =    \
515
0
        &(elm2)->field.tqe_next;       \
516
0
  else                \
517
0
    (head)->tqh_last = &(elm2)->field.tqe_next;   \
518
0
  (elm2)->field.tqe_prev = (elm)->field.tqe_prev;     \
519
0
  *(elm2)->field.tqe_prev = (elm2);       \
520
0
  _Q_INVALIDATE((elm)->field.tqe_prev);       \
521
0
  _Q_INVALIDATE((elm)->field.tqe_next);       \
522
0
} while (0)
523
524
411k
#define TAILQ_CONCAT(head1, head2, field) do {       \
525
411k
  if (!TAILQ_EMPTY(head2)) {         \
526
203k
    *(head1)->tqh_last = (head2)->tqh_first;    \
527
203k
    (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
528
203k
    (head1)->tqh_last = (head2)->tqh_last;      \
529
203k
    TAILQ_INIT((head2));          \
530
203k
  }                \
531
411k
} while (0)
532
533
#endif  /* !_COMPAT_QUEUE_H_ */