1*7c478bd9Sstevel@tonic-gate /*- 2*7c478bd9Sstevel@tonic-gate * See the file LICENSE for redistribution information. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996, 1997 5*7c478bd9Sstevel@tonic-gate * Sleepycat Software. All rights reserved. 6*7c478bd9Sstevel@tonic-gate * 7*7c478bd9Sstevel@tonic-gate * @(#)shqueue.h 8.12 (Sleepycat) 9/10/97 8*7c478bd9Sstevel@tonic-gate * %W% (Sun) %G% 9*7c478bd9Sstevel@tonic-gate */ 10*7c478bd9Sstevel@tonic-gate /* 11*7c478bd9Sstevel@tonic-gate * Copyright (c) 1998 by Sun Microsystems, Inc. 12*7c478bd9Sstevel@tonic-gate * All rights reserved. 13*7c478bd9Sstevel@tonic-gate */ 14*7c478bd9Sstevel@tonic-gate 15*7c478bd9Sstevel@tonic-gate #ifndef _SYS_SHQUEUE_H_ 16*7c478bd9Sstevel@tonic-gate #define _SYS_SHQUEUE_H_ 17*7c478bd9Sstevel@tonic-gate 18*7c478bd9Sstevel@tonic-gate /* 19*7c478bd9Sstevel@tonic-gate * This file defines three types of data structures: lists, tail queues, and 20*7c478bd9Sstevel@tonic-gate * circular queues, similarly to the include file <sys/queue.h>. 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * The difference is that this set of macros can be used for structures that 23*7c478bd9Sstevel@tonic-gate * reside in shared memory that may be mapped at different addresses in each 24*7c478bd9Sstevel@tonic-gate * process. In most cases, the macros for shared structures exactly mirror 25*7c478bd9Sstevel@tonic-gate * the normal macros, although the macro calls require an additional type 26*7c478bd9Sstevel@tonic-gate * parameter, only used by the HEAD and ENTRY macros of the standard macros. 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * For details on the use of these macros, see the queue(3) manual page. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate /* 32*7c478bd9Sstevel@tonic-gate * Shared list definitions. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate #define SH_LIST_HEAD(name) \ 35*7c478bd9Sstevel@tonic-gate struct name { \ 36*7c478bd9Sstevel@tonic-gate ssize_t slh_first; /* first element */ \ 37*7c478bd9Sstevel@tonic-gate } 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #define SH_LIST_ENTRY \ 40*7c478bd9Sstevel@tonic-gate struct { \ 41*7c478bd9Sstevel@tonic-gate ssize_t sle_next; /* relative offset next element */ \ 42*7c478bd9Sstevel@tonic-gate ssize_t sle_prev; /* relative offset of prev element */ \ 43*7c478bd9Sstevel@tonic-gate } 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * Shared list functions. Since we use relative offsets for pointers, 47*7c478bd9Sstevel@tonic-gate * 0 is a valid offset. Therefore, we use -1 to indicate end of list. 48*7c478bd9Sstevel@tonic-gate * The macros ending in "P" return pointers without checking for end 49*7c478bd9Sstevel@tonic-gate * of list, the others check for end of list and evaluate to either a 50*7c478bd9Sstevel@tonic-gate * pointer or NULL. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define SH_LIST_FIRSTP(head, type) \ 54*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)) 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #define SH_LIST_FIRST(head, type) \ 57*7c478bd9Sstevel@tonic-gate ((head)->slh_first == -1 ? NULL : \ 58*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))) 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #define SH_LIST_NEXTP(elm, field, type) \ 61*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)) 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate #define SH_LIST_NEXT(elm, field, type) \ 64*7c478bd9Sstevel@tonic-gate ((elm)->field.sle_next == -1 ? NULL : \ 65*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))) 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate #define SH_LIST_PREV(elm, field) \ 68*7c478bd9Sstevel@tonic-gate ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev)) 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate #define SH_PTR_TO_OFF(src, dest) \ 71*7c478bd9Sstevel@tonic-gate ((ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src)))) 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #define SH_LIST_END(head) NULL 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate /* 76*7c478bd9Sstevel@tonic-gate * Take the element's next pointer and calculate what the corresponding 77*7c478bd9Sstevel@tonic-gate * Prev pointer should be -- basically it is the negation plus the offset 78*7c478bd9Sstevel@tonic-gate * of the next field in the structure. 79*7c478bd9Sstevel@tonic-gate */ 80*7c478bd9Sstevel@tonic-gate #define SH_LIST_NEXT_TO_PREV(elm, field) \ 81*7c478bd9Sstevel@tonic-gate (-(elm)->field.sle_next + SH_PTR_TO_OFF(elm, &(elm)->field.sle_next)) 82*7c478bd9Sstevel@tonic-gate 83*7c478bd9Sstevel@tonic-gate #define SH_LIST_INIT(head) (head)->slh_first = -1 84*7c478bd9Sstevel@tonic-gate 85*7c478bd9Sstevel@tonic-gate #define SH_LIST_INSERT_AFTER(listelm, elm, field, type) do { \ 86*7c478bd9Sstevel@tonic-gate if ((listelm)->field.sle_next != -1) { \ 87*7c478bd9Sstevel@tonic-gate (elm)->field.sle_next = SH_PTR_TO_OFF(elm, \ 88*7c478bd9Sstevel@tonic-gate SH_LIST_NEXTP(listelm, field, type)); \ 89*7c478bd9Sstevel@tonic-gate SH_LIST_NEXTP(listelm, field, type)->field.sle_prev = \ 90*7c478bd9Sstevel@tonic-gate SH_LIST_NEXT_TO_PREV(elm, field); \ 91*7c478bd9Sstevel@tonic-gate } else \ 92*7c478bd9Sstevel@tonic-gate (elm)->field.sle_next = -1; \ 93*7c478bd9Sstevel@tonic-gate (listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm); \ 94*7c478bd9Sstevel@tonic-gate (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field); \ 95*7c478bd9Sstevel@tonic-gate } while (0) 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate #define SH_LIST_INSERT_HEAD(head, elm, field, type) do { \ 98*7c478bd9Sstevel@tonic-gate if ((head)->slh_first != -1) { \ 99*7c478bd9Sstevel@tonic-gate (elm)->field.sle_next = \ 100*7c478bd9Sstevel@tonic-gate (head)->slh_first - SH_PTR_TO_OFF(head, elm); \ 101*7c478bd9Sstevel@tonic-gate SH_LIST_FIRSTP(head, type)->field.sle_prev = \ 102*7c478bd9Sstevel@tonic-gate SH_LIST_NEXT_TO_PREV(elm, field); \ 103*7c478bd9Sstevel@tonic-gate } else \ 104*7c478bd9Sstevel@tonic-gate (elm)->field.sle_next = -1; \ 105*7c478bd9Sstevel@tonic-gate (head)->slh_first = SH_PTR_TO_OFF(head, elm); \ 106*7c478bd9Sstevel@tonic-gate (elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first); \ 107*7c478bd9Sstevel@tonic-gate } while (0) 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate #define SH_LIST_REMOVE(elm, field, type) do { \ 110*7c478bd9Sstevel@tonic-gate if ((elm)->field.sle_next != -1) { \ 111*7c478bd9Sstevel@tonic-gate SH_LIST_NEXTP(elm, field, type)->field.sle_prev = \ 112*7c478bd9Sstevel@tonic-gate (elm)->field.sle_prev - (elm)->field.sle_next; \ 113*7c478bd9Sstevel@tonic-gate *SH_LIST_PREV(elm, field) += (elm)->field.sle_next; \ 114*7c478bd9Sstevel@tonic-gate } else \ 115*7c478bd9Sstevel@tonic-gate *SH_LIST_PREV(elm, field) = -1; \ 116*7c478bd9Sstevel@tonic-gate } while (0) 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /* 119*7c478bd9Sstevel@tonic-gate * Shared tail queue definitions. 120*7c478bd9Sstevel@tonic-gate */ 121*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_HEAD(name) \ 122*7c478bd9Sstevel@tonic-gate struct name { \ 123*7c478bd9Sstevel@tonic-gate ssize_t stqh_first; /* relative offset of first element */ \ 124*7c478bd9Sstevel@tonic-gate ssize_t stqh_last; /* relative offset of last's next */ \ 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_ENTRY \ 128*7c478bd9Sstevel@tonic-gate struct { \ 129*7c478bd9Sstevel@tonic-gate ssize_t stqe_next; /* relative offset of next element */ \ 130*7c478bd9Sstevel@tonic-gate ssize_t stqe_prev; /* relative offset of prev's next */ \ 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate 133*7c478bd9Sstevel@tonic-gate /* 134*7c478bd9Sstevel@tonic-gate * Shared tail queue functions. 135*7c478bd9Sstevel@tonic-gate */ 136*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_FIRSTP(head, type) \ 137*7c478bd9Sstevel@tonic-gate ((struct type *)((u_int8_t *)(head) + (head)->stqh_first)) 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_FIRST(head, type) \ 140*7c478bd9Sstevel@tonic-gate ((head)->stqh_first == -1 ? NULL : SH_TAILQ_FIRSTP(head, type)) 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_NEXTP(elm, field, type) \ 143*7c478bd9Sstevel@tonic-gate ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next)) 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_NEXT(elm, field, type) \ 146*7c478bd9Sstevel@tonic-gate ((elm)->field.stqe_next == -1 ? NULL : SH_TAILQ_NEXTP(elm, field, type)) 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_PREVP(elm, field) \ 149*7c478bd9Sstevel@tonic-gate ((ssize_t *)((u_int8_t *)(elm) + (elm)->field.stqe_prev)) 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_LAST(head) \ 152*7c478bd9Sstevel@tonic-gate ((ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last)) 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_NEXT_TO_PREV(elm, field) \ 155*7c478bd9Sstevel@tonic-gate (-(elm)->field.stqe_next + SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next)) 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_END(head) NULL 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_INIT(head) { \ 160*7c478bd9Sstevel@tonic-gate (head)->stqh_first = -1; \ 161*7c478bd9Sstevel@tonic-gate (head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first); \ 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_INSERT_HEAD(head, elm, field, type) do { \ 165*7c478bd9Sstevel@tonic-gate if ((head)->stqh_first != -1) { \ 166*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_next = \ 167*7c478bd9Sstevel@tonic-gate (head)->stqh_first - SH_PTR_TO_OFF(head, elm); \ 168*7c478bd9Sstevel@tonic-gate SH_TAILQ_FIRSTP(head, type)->field.stqe_prev = \ 169*7c478bd9Sstevel@tonic-gate SH_TAILQ_NEXT_TO_PREV(elm, field); \ 170*7c478bd9Sstevel@tonic-gate } else { \ 171*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_next = -1; \ 172*7c478bd9Sstevel@tonic-gate (head)->stqh_last = \ 173*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \ 174*7c478bd9Sstevel@tonic-gate } \ 175*7c478bd9Sstevel@tonic-gate (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ 176*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_prev = \ 177*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(elm, &(head)->stqh_first); \ 178*7c478bd9Sstevel@tonic-gate } while (0) 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_INSERT_TAIL(head, elm, field) do { \ 181*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_next = -1; \ 182*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_prev = \ 183*7c478bd9Sstevel@tonic-gate -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last; \ 184*7c478bd9Sstevel@tonic-gate if ((head)->stqh_last == \ 185*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF((head), &(head)->stqh_first)) \ 186*7c478bd9Sstevel@tonic-gate (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \ 187*7c478bd9Sstevel@tonic-gate else \ 188*7c478bd9Sstevel@tonic-gate *SH_TAILQ_LAST(head) = -(head)->stqh_last + \ 189*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) + \ 190*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(head, elm); \ 191*7c478bd9Sstevel@tonic-gate (head)->stqh_last = \ 192*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(head, &((elm)->field.stqe_next)); \ 193*7c478bd9Sstevel@tonic-gate } while (0) 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do { \ 196*7c478bd9Sstevel@tonic-gate if ((listelm)->field.stqe_next != -1) { \ 197*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_next = (listelm)->field.stqe_next - \ 198*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(listelm, elm); \ 199*7c478bd9Sstevel@tonic-gate SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev = \ 200*7c478bd9Sstevel@tonic-gate SH_TAILQ_NEXT_TO_PREV(elm, field); \ 201*7c478bd9Sstevel@tonic-gate } else { \ 202*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_next = -1; \ 203*7c478bd9Sstevel@tonic-gate (head)->stqh_last = \ 204*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(head, &elm->field.stqe_next); \ 205*7c478bd9Sstevel@tonic-gate } \ 206*7c478bd9Sstevel@tonic-gate (listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm); \ 207*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field); \ 208*7c478bd9Sstevel@tonic-gate } while (0) 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate #define SH_TAILQ_REMOVE(head, elm, field, type) do { \ 211*7c478bd9Sstevel@tonic-gate if ((elm)->field.stqe_next != -1) { \ 212*7c478bd9Sstevel@tonic-gate SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev = \ 213*7c478bd9Sstevel@tonic-gate (elm)->field.stqe_prev + \ 214*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm, \ 215*7c478bd9Sstevel@tonic-gate field, type), elm); \ 216*7c478bd9Sstevel@tonic-gate *SH_TAILQ_PREVP(elm, field) += elm->field.stqe_next; \ 217*7c478bd9Sstevel@tonic-gate } else { \ 218*7c478bd9Sstevel@tonic-gate (head)->stqh_last = (elm)->field.stqe_prev + \ 219*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(head, elm); \ 220*7c478bd9Sstevel@tonic-gate *SH_TAILQ_PREVP(elm, field) = -1; \ 221*7c478bd9Sstevel@tonic-gate } \ 222*7c478bd9Sstevel@tonic-gate } while (0) 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* 225*7c478bd9Sstevel@tonic-gate * Shared circular queue definitions. 226*7c478bd9Sstevel@tonic-gate */ 227*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_HEAD(name) \ 228*7c478bd9Sstevel@tonic-gate struct name { \ 229*7c478bd9Sstevel@tonic-gate ssize_t scqh_first; /* first element */ \ 230*7c478bd9Sstevel@tonic-gate ssize_t scqh_last; /* last element */ \ 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate 233*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_ENTRY \ 234*7c478bd9Sstevel@tonic-gate struct { \ 235*7c478bd9Sstevel@tonic-gate ssize_t scqe_next; /* next element */ \ 236*7c478bd9Sstevel@tonic-gate ssize_t scqe_prev; /* previous element */ \ 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * Shared circular queue functions. 241*7c478bd9Sstevel@tonic-gate */ 242*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_FIRSTP(head, type) \ 243*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(head)) + (head)->scqh_first)) 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_FIRST(head, type) \ 246*7c478bd9Sstevel@tonic-gate ((head)->scqh_first == -1 ? \ 247*7c478bd9Sstevel@tonic-gate (void *)head : SH_CIRCLEQ_FIRSTP(head, type)) 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_LASTP(head, type) \ 250*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(head)) + (head)->scqh_last)) 251*7c478bd9Sstevel@tonic-gate 252*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_LAST(head, type) \ 253*7c478bd9Sstevel@tonic-gate ((head)->scqh_last == -1 ? (void *)head : SH_CIRCLEQ_LASTP(head, type)) 254*7c478bd9Sstevel@tonic-gate 255*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_NEXTP(elm, field, type) \ 256*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.scqe_next)) 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_NEXT(head, elm, field, type) \ 259*7c478bd9Sstevel@tonic-gate ((elm)->field.scqe_next == SH_PTR_TO_OFF(elm, head) ? \ 260*7c478bd9Sstevel@tonic-gate (void *)head : SH_CIRCLEQ_NEXTP(elm, field, type)) 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_PREVP(elm, field, type) \ 263*7c478bd9Sstevel@tonic-gate ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.scqe_prev)) 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_PREV(head, elm, field, type) \ 266*7c478bd9Sstevel@tonic-gate ((elm)->field.scqe_prev == SH_PTR_TO_OFF(elm, head) ? \ 267*7c478bd9Sstevel@tonic-gate (void *)head : SH_CIRCLEQ_PREVP(elm, field, type)) 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_END(head) ((void *)(head)) 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_INIT(head) { \ 272*7c478bd9Sstevel@tonic-gate (head)->scqh_first = 0; \ 273*7c478bd9Sstevel@tonic-gate (head)->scqh_last = 0; \ 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field, type) do { \ 277*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev = SH_PTR_TO_OFF(elm, listelm); \ 278*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next = (listelm)->field.scqe_next + \ 279*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev; \ 280*7c478bd9Sstevel@tonic-gate if (SH_CIRCLEQ_NEXTP(listelm, field, type) == (void *)head) \ 281*7c478bd9Sstevel@tonic-gate (head)->scqh_last = SH_PTR_TO_OFF(head, elm); \ 282*7c478bd9Sstevel@tonic-gate else \ 283*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_NEXTP(listelm, \ 284*7c478bd9Sstevel@tonic-gate field, type)->field.scqe_prev = \ 285*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(SH_CIRCLEQ_NEXTP(listelm, \ 286*7c478bd9Sstevel@tonic-gate field, type), elm); \ 287*7c478bd9Sstevel@tonic-gate (listelm)->field.scqe_next = -(elm)->field.scqe_prev; \ 288*7c478bd9Sstevel@tonic-gate } while (0) 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field, type) do { \ 291*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next = SH_PTR_TO_OFF(elm, listelm); \ 292*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev = (elm)->field.scqe_next - \ 293*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_PREVP(listelm, field, type)->field.scqe_next;\ 294*7c478bd9Sstevel@tonic-gate if (SH_CIRCLEQ_PREVP(listelm, field, type) == (void *)(head)) \ 295*7c478bd9Sstevel@tonic-gate (head)->scqh_first = SH_PTR_TO_OFF(head, elm); \ 296*7c478bd9Sstevel@tonic-gate else \ 297*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_PREVP(listelm, \ 298*7c478bd9Sstevel@tonic-gate field, type)->field.scqe_next = \ 299*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(SH_CIRCLEQ_PREVP(listelm, \ 300*7c478bd9Sstevel@tonic-gate field, type), elm); \ 301*7c478bd9Sstevel@tonic-gate (listelm)->field.scqe_prev = -(elm)->field.scqe_next; \ 302*7c478bd9Sstevel@tonic-gate } while (0) 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_INSERT_HEAD(head, elm, field, type) do { \ 305*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev = SH_PTR_TO_OFF(elm, head); \ 306*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next = (head)->scqh_first + \ 307*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev; \ 308*7c478bd9Sstevel@tonic-gate if ((head)->scqh_last == 0) \ 309*7c478bd9Sstevel@tonic-gate (head)->scqh_last = -(elm)->field.scqe_prev; \ 310*7c478bd9Sstevel@tonic-gate else \ 311*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_FIRSTP(head, type)->field.scqe_prev = \ 312*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(SH_CIRCLEQ_FIRSTP(head, type), elm); \ 313*7c478bd9Sstevel@tonic-gate (head)->scqh_first = -(elm)->field.scqe_prev; \ 314*7c478bd9Sstevel@tonic-gate } while (0) 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_INSERT_TAIL(head, elm, field, type) do { \ 317*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next = SH_PTR_TO_OFF(elm, head); \ 318*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev = (head)->scqh_last + \ 319*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next; \ 320*7c478bd9Sstevel@tonic-gate if ((head)->scqh_first == 0) \ 321*7c478bd9Sstevel@tonic-gate (head)->scqh_first = -(elm)->field.scqe_next; \ 322*7c478bd9Sstevel@tonic-gate else \ 323*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_LASTP(head, type)->field.scqe_next = \ 324*7c478bd9Sstevel@tonic-gate SH_PTR_TO_OFF(SH_CIRCLEQ_LASTP(head, type), elm); \ 325*7c478bd9Sstevel@tonic-gate (head)->scqh_last = -(elm)->field.scqe_next; \ 326*7c478bd9Sstevel@tonic-gate } while (0) 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate #define SH_CIRCLEQ_REMOVE(head, elm, field, type) do { \ 329*7c478bd9Sstevel@tonic-gate if (SH_CIRCLEQ_NEXTP(elm, field, type) == (void *)(head)) \ 330*7c478bd9Sstevel@tonic-gate (head)->scqh_last += (elm)->field.scqe_prev; \ 331*7c478bd9Sstevel@tonic-gate else \ 332*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_NEXTP(elm, field, type)->field.scqe_prev += \ 333*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_prev; \ 334*7c478bd9Sstevel@tonic-gate if (SH_CIRCLEQ_PREVP(elm, field, type) == (void *)(head)) \ 335*7c478bd9Sstevel@tonic-gate (head)->scqh_first += (elm)->field.scqe_next; \ 336*7c478bd9Sstevel@tonic-gate else \ 337*7c478bd9Sstevel@tonic-gate SH_CIRCLEQ_PREVP(elm, field, type)->field.scqe_next += \ 338*7c478bd9Sstevel@tonic-gate (elm)->field.scqe_next; \ 339*7c478bd9Sstevel@tonic-gate } while (0) 340*7c478bd9Sstevel@tonic-gate #endif /* !_SYS_SHQUEUE_H_ */ 341