00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef _SYS_SHQUEUE_H_
00011 #define _SYS_SHQUEUE_H_
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #if defined(__cplusplus)
00035 extern "C" {
00036 #endif
00037
00038
00039
00040
00041 #define SH_LIST_HEAD(name) \
00042 struct name { \
00043 ssize_t slh_first; \
00044 }
00045
00046 #define SH_LIST_HEAD_INITIALIZER(head) \
00047 { -1 }
00048
00049 #define SH_LIST_ENTRY \
00050 struct { \
00051 ssize_t sle_next; \
00052 ssize_t sle_prev; \
00053 }
00054
00055
00056
00057
00058
00059 #define SH_LIST_EMPTY(head) \
00060 ((head)->slh_first == -1)
00061
00062 #define SH_LIST_FIRSTP(head, type) \
00063 ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first))
00064
00065 #define SH_LIST_FIRST(head, type) \
00066 (SH_LIST_EMPTY(head) ? NULL : \
00067 ((struct type *)(((u_int8_t *)(head)) + (head)->slh_first)))
00068
00069 #define SH_LIST_NEXTP(elm, field, type) \
00070 ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next))
00071
00072 #define SH_LIST_NEXT(elm, field, type) \
00073 ((elm)->field.sle_next == -1 ? NULL : \
00074 ((struct type *)(((u_int8_t *)(elm)) + (elm)->field.sle_next)))
00075
00076
00077
00078
00079
00080
00081 #define __SH_LIST_PREV_OFF(elm, field) \
00082 ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.sle_prev))
00083
00084 #define SH_LIST_PREV(elm, field, type) \
00085 (struct type *)((ssize_t)elm - (*__SH_LIST_PREV_OFF(elm, field)))
00086
00087 #define SH_LIST_FOREACH(var, head, field, type) \
00088 for ((var) = SH_LIST_FIRST((head), type); \
00089 (var); \
00090 (var) = SH_LIST_NEXT((var), field, type))
00091
00092 #define SH_PTR_TO_OFF(src, dest) \
00093 ((ssize_t)(((u_int8_t *)(dest)) - ((u_int8_t *)(src))))
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 #define SH_LIST_NEXT_TO_PREV(elm, field) \
00108 (((elm)->field.sle_next == -1 ? 0 : -(elm)->field.sle_next) + \
00109 SH_PTR_TO_OFF(elm, &(elm)->field.sle_next))
00110
00111 #define SH_LIST_INIT(head) (head)->slh_first = -1
00112
00113 #define SH_LIST_INSERT_BEFORE(head, listelm, elm, field, type) do { \
00114 if (listelm == SH_LIST_FIRST(head, type)) { \
00115 SH_LIST_INSERT_HEAD(head, elm, field, type); \
00116 } else { \
00117 (elm)->field.sle_next = SH_PTR_TO_OFF(elm, listelm); \
00118 (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV( \
00119 SH_LIST_PREV((listelm), field, type), field) + \
00120 (elm)->field.sle_next; \
00121 (SH_LIST_PREV(listelm, field, type))->field.sle_next = \
00122 (SH_PTR_TO_OFF((SH_LIST_PREV(listelm, field, \
00123 type)), elm)); \
00124 (listelm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(elm, field); \
00125 } \
00126 } while (0)
00127
00128 #define SH_LIST_INSERT_AFTER(listelm, elm, field, type) do { \
00129 if ((listelm)->field.sle_next != -1) { \
00130 (elm)->field.sle_next = SH_PTR_TO_OFF(elm, \
00131 SH_LIST_NEXTP(listelm, field, type)); \
00132 SH_LIST_NEXTP(listelm, field, type)->field.sle_prev = \
00133 SH_LIST_NEXT_TO_PREV(elm, field); \
00134 } else \
00135 (elm)->field.sle_next = -1; \
00136 (listelm)->field.sle_next = SH_PTR_TO_OFF(listelm, elm); \
00137 (elm)->field.sle_prev = SH_LIST_NEXT_TO_PREV(listelm, field); \
00138 } while (0)
00139
00140 #define SH_LIST_INSERT_HEAD(head, elm, field, type) do { \
00141 if ((head)->slh_first != -1) { \
00142 (elm)->field.sle_next = \
00143 (head)->slh_first - SH_PTR_TO_OFF(head, elm); \
00144 SH_LIST_FIRSTP(head, type)->field.sle_prev = \
00145 SH_LIST_NEXT_TO_PREV(elm, field); \
00146 } else \
00147 (elm)->field.sle_next = -1; \
00148 (head)->slh_first = SH_PTR_TO_OFF(head, elm); \
00149 (elm)->field.sle_prev = SH_PTR_TO_OFF(elm, &(head)->slh_first); \
00150 } while (0)
00151
00152 #define SH_LIST_REMOVE(elm, field, type) do { \
00153 if ((elm)->field.sle_next != -1) { \
00154 SH_LIST_NEXTP(elm, field, type)->field.sle_prev = \
00155 (elm)->field.sle_prev - (elm)->field.sle_next; \
00156 *__SH_LIST_PREV_OFF(elm, field) += (elm)->field.sle_next;\
00157 } else \
00158 *__SH_LIST_PREV_OFF(elm, field) = -1; \
00159 } while (0)
00160
00161 #define SH_LIST_REMOVE_HEAD(head, field, type) do { \
00162 if (!SH_LIST_EMPTY(head)) { \
00163 SH_LIST_REMOVE(SH_LIST_FIRSTP(head, type), field, type);\
00164 } \
00165 } while (0)
00166
00167
00168
00169
00170 #define SH_TAILQ_HEAD(name) \
00171 struct name { \
00172 ssize_t stqh_first; \
00173 ssize_t stqh_last; \
00174 }
00175
00176 #define SH_TAILQ_HEAD_INITIALIZER(head) \
00177 { -1, 0 }
00178
00179 #define SH_TAILQ_ENTRY \
00180 struct { \
00181 ssize_t stqe_next; \
00182 ssize_t stqe_prev; \
00183 }
00184
00185
00186
00187
00188
00189 #define SH_TAILQ_EMPTY(head) \
00190 ((head)->stqh_first == -1)
00191
00192 #define SH_TAILQ_FIRSTP(head, type) \
00193 ((struct type *)((u_int8_t *)(head) + (head)->stqh_first))
00194
00195 #define SH_TAILQ_FIRST(head, type) \
00196 (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_FIRSTP(head, type))
00197
00198 #define SH_TAILQ_NEXTP(elm, field, type) \
00199 ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next))
00200
00201 #define SH_TAILQ_NEXT(elm, field, type) \
00202 ((elm)->field.stqe_next == -1 ? NULL : \
00203 ((struct type *)((u_int8_t *)(elm) + (elm)->field.stqe_next)))
00204
00205
00206
00207
00208
00209
00210
00211 #define __SH_TAILQ_PREV_OFF(elm, field) \
00212 ((ssize_t *)(((u_int8_t *)(elm)) + (elm)->field.stqe_prev))
00213
00214 #define SH_TAILQ_PREVP(elm, field, type) \
00215 (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field)))
00216
00217 #define SH_TAILQ_PREV(head, elm, field, type) \
00218 (((elm) == SH_TAILQ_FIRST(head, type)) ? NULL : \
00219 (struct type *)((ssize_t)elm - (*__SH_TAILQ_PREV_OFF(elm, field))))
00220
00221
00222
00223
00224
00225
00226
00227 #define __SH_TAILQ_LAST_OFF(head) \
00228 ((ssize_t *)(((u_int8_t *)(head)) + (head)->stqh_last))
00229
00230 #define SH_TAILQ_LASTP(head, field, type) \
00231 ((struct type *)((ssize_t)(head) + \
00232 ((ssize_t)((head)->stqh_last) - \
00233 ((ssize_t)SH_PTR_TO_OFF(SH_TAILQ_FIRST(head, type), \
00234 &(SH_TAILQ_FIRSTP(head, type)->field.stqe_next))))))
00235
00236 #define SH_TAILQ_LAST(head, field, type) \
00237 (SH_TAILQ_EMPTY(head) ? NULL : SH_TAILQ_LASTP(head, field, type))
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 #define SH_TAILQ_NEXT_TO_PREV(elm, field) \
00249 (((elm)->field.stqe_next == -1 ? 0 : \
00250 (-(elm)->field.stqe_next) + \
00251 SH_PTR_TO_OFF(elm, &(elm)->field.stqe_next)))
00252
00253 #define SH_TAILQ_FOREACH(var, head, field, type) \
00254 for ((var) = SH_TAILQ_FIRST((head), type); \
00255 (var); \
00256 (var) = SH_TAILQ_NEXT((var), field, type))
00257
00258 #define SH_TAILQ_FOREACH_REVERSE(var, head, field, type) \
00259 for ((var) = SH_TAILQ_LAST((head), field, type); \
00260 (var); \
00261 (var) = SH_TAILQ_PREV((head), (var), field, type))
00262
00263 #define SH_TAILQ_INIT(head) { \
00264 (head)->stqh_first = -1; \
00265 (head)->stqh_last = SH_PTR_TO_OFF(head, &(head)->stqh_first); \
00266 }
00267
00268 #define SH_TAILQ_INSERT_HEAD(head, elm, field, type) do { \
00269 if ((head)->stqh_first != -1) { \
00270 (elm)->field.stqe_next = \
00271 (head)->stqh_first - SH_PTR_TO_OFF(head, elm); \
00272 SH_TAILQ_FIRSTP(head, type)->field.stqe_prev = \
00273 SH_TAILQ_NEXT_TO_PREV(elm, field); \
00274 } else { \
00275 (head)->stqh_last = \
00276 SH_PTR_TO_OFF(head, &(elm)->field.stqe_next); \
00277 (elm)->field.stqe_next = -1; \
00278 } \
00279 (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \
00280 (elm)->field.stqe_prev = \
00281 SH_PTR_TO_OFF(elm, &(head)->stqh_first); \
00282 } while (0)
00283
00284 #define SH_TAILQ_INSERT_TAIL(head, elm, field) do { \
00285 (elm)->field.stqe_next = -1; \
00286 (elm)->field.stqe_prev = \
00287 -SH_PTR_TO_OFF(head, elm) + (head)->stqh_last; \
00288 if ((head)->stqh_last == \
00289 SH_PTR_TO_OFF((head), &(head)->stqh_first)) \
00290 (head)->stqh_first = SH_PTR_TO_OFF(head, elm); \
00291 else \
00292 *__SH_TAILQ_LAST_OFF(head) = -(head)->stqh_last + \
00293 SH_PTR_TO_OFF((elm), &(elm)->field.stqe_next) + \
00294 SH_PTR_TO_OFF(head, elm); \
00295 (head)->stqh_last = \
00296 SH_PTR_TO_OFF(head, &((elm)->field.stqe_next)); \
00297 } while (0)
00298
00299 #define SH_TAILQ_INSERT_BEFORE(head, listelm, elm, field, type) do { \
00300 if (listelm == SH_TAILQ_FIRST(head, type)) { \
00301 SH_TAILQ_INSERT_HEAD(head, elm, field, type); \
00302 } else { \
00303 (elm)->field.stqe_next = SH_PTR_TO_OFF(elm, listelm); \
00304 (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV( \
00305 SH_TAILQ_PREVP((listelm), field, type), field) + \
00306 (elm)->field.stqe_next; \
00307 (SH_TAILQ_PREVP(listelm, field, type))->field.stqe_next =\
00308 (SH_PTR_TO_OFF((SH_TAILQ_PREVP(listelm, field, type)), \
00309 elm)); \
00310 (listelm)->field.stqe_prev = \
00311 SH_TAILQ_NEXT_TO_PREV(elm, field); \
00312 } \
00313 } while (0)
00314
00315 #define SH_TAILQ_INSERT_AFTER(head, listelm, elm, field, type) do { \
00316 if ((listelm)->field.stqe_next != -1) { \
00317 (elm)->field.stqe_next = (listelm)->field.stqe_next - \
00318 SH_PTR_TO_OFF(listelm, elm); \
00319 SH_TAILQ_NEXTP(listelm, field, type)->field.stqe_prev = \
00320 SH_TAILQ_NEXT_TO_PREV(elm, field); \
00321 } else { \
00322 (elm)->field.stqe_next = -1; \
00323 (head)->stqh_last = \
00324 SH_PTR_TO_OFF(head, &elm->field.stqe_next); \
00325 } \
00326 (listelm)->field.stqe_next = SH_PTR_TO_OFF(listelm, elm); \
00327 (elm)->field.stqe_prev = SH_TAILQ_NEXT_TO_PREV(listelm, field); \
00328 } while (0)
00329
00330 #define SH_TAILQ_REMOVE(head, elm, field, type) do { \
00331 if ((elm)->field.stqe_next != -1) { \
00332 SH_TAILQ_NEXTP(elm, field, type)->field.stqe_prev = \
00333 (elm)->field.stqe_prev + \
00334 SH_PTR_TO_OFF(SH_TAILQ_NEXTP(elm, \
00335 field, type), elm); \
00336 *__SH_TAILQ_PREV_OFF(elm, field) += elm->field.stqe_next;\
00337 } else { \
00338 (head)->stqh_last = (elm)->field.stqe_prev + \
00339 SH_PTR_TO_OFF(head, elm); \
00340 *__SH_TAILQ_PREV_OFF(elm, field) = -1; \
00341 } \
00342 } while (0)
00343
00344 #if defined(__cplusplus)
00345 }
00346 #endif
00347 #endif