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