queue.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*-
  2. * Copyright (c) 1991, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 4. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. *
  29. * @(#)queue.h 8.5 (Berkeley) 8/20/94
  30. * $FreeBSD$
  31. */
  32. #ifndef _SYS_QUEUE_H_
  33. #define _SYS_QUEUE_H_
  34. #define QMD_SAVELINK(name, link)
  35. #define TRASHIT(x)
  36. /*
  37. * Singly-linked List declarations.
  38. */
  39. #define SLIST_HEAD(name, type) \
  40. struct name { \
  41. struct type *slh_first; /* first element */ \
  42. }
  43. #define SLIST_HEAD_INITIALIZER(head) \
  44. { NULL }
  45. #define SLIST_ENTRY(type) \
  46. struct { \
  47. struct type *sle_next; /* next element */ \
  48. }
  49. /*
  50. * Singly-linked List functions.
  51. */
  52. #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
  53. #define SLIST_FIRST(head) ((head)->slh_first)
  54. #define SLIST_FOREACH(var, head, field) \
  55. for ((var) = SLIST_FIRST((head)); \
  56. (var); \
  57. (var) = SLIST_NEXT((var), field))
  58. #define SLIST_FOREACH_SAFE(var, head, field, tvar) \
  59. for ((var) = SLIST_FIRST((head)); \
  60. (var) && ((tvar) = SLIST_NEXT((var), field), 1); \
  61. (var) = (tvar))
  62. #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
  63. for ((varp) = &SLIST_FIRST((head)); \
  64. ((var) = *(varp)) != NULL; \
  65. (varp) = &SLIST_NEXT((var), field))
  66. #define SLIST_INIT(head) do { \
  67. SLIST_FIRST((head)) = NULL; \
  68. } while (0)
  69. #define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
  70. SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
  71. SLIST_NEXT((slistelm), field) = (elm); \
  72. } while (0)
  73. #define SLIST_INSERT_HEAD(head, elm, field) do { \
  74. SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
  75. SLIST_FIRST((head)) = (elm); \
  76. } while (0)
  77. #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
  78. #define SLIST_REMOVE(head, elm, type, field) do { \
  79. QMD_SAVELINK(oldnext, (elm)->field.sle_next); \
  80. if (SLIST_FIRST((head)) == (elm)) { \
  81. SLIST_REMOVE_HEAD((head), field); \
  82. } \
  83. else { \
  84. struct type *curelm = SLIST_FIRST((head)); \
  85. while (SLIST_NEXT(curelm, field) != (elm)) \
  86. curelm = SLIST_NEXT(curelm, field); \
  87. SLIST_REMOVE_AFTER(curelm, field); \
  88. } \
  89. TRASHIT(*oldnext); \
  90. } while (0)
  91. #define SLIST_REMOVE_AFTER(elm, field) do { \
  92. SLIST_NEXT(elm, field) = \
  93. SLIST_NEXT(SLIST_NEXT(elm, field), field); \
  94. } while (0)
  95. #define SLIST_REMOVE_HEAD(head, field) do { \
  96. SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
  97. } while (0)
  98. /*
  99. * Singly-linked Tail queue declarations.
  100. */
  101. #define STAILQ_HEAD(name, type) \
  102. struct name { \
  103. struct type *stqh_first;/* first element */ \
  104. struct type **stqh_last;/* addr of last next element */ \
  105. }
  106. #define STAILQ_HEAD_INITIALIZER(head) \
  107. { NULL, &(head).stqh_first }
  108. #define STAILQ_ENTRY(type) \
  109. struct { \
  110. struct type *stqe_next; /* next element */ \
  111. }
  112. /*
  113. * Singly-linked Tail queue functions.
  114. */
  115. #define STAILQ_CONCAT(head1, head2) do { \
  116. if (!STAILQ_EMPTY((head2))) { \
  117. *(head1)->stqh_last = (head2)->stqh_first; \
  118. (head1)->stqh_last = (head2)->stqh_last; \
  119. STAILQ_INIT((head2)); \
  120. } \
  121. } while (0)
  122. #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
  123. #define STAILQ_FIRST(head) ((head)->stqh_first)
  124. #define STAILQ_FOREACH(var, head, field) \
  125. for((var) = STAILQ_FIRST((head)); \
  126. (var); \
  127. (var) = STAILQ_NEXT((var), field))
  128. #define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
  129. for ((var) = STAILQ_FIRST((head)); \
  130. (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
  131. (var) = (tvar))
  132. #define STAILQ_INIT(head) do { \
  133. STAILQ_FIRST((head)) = NULL; \
  134. (head)->stqh_last = &STAILQ_FIRST((head)); \
  135. } while (0)
  136. #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
  137. if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
  138. (head)->stqh_last = &STAILQ_NEXT((elm), field); \
  139. STAILQ_NEXT((tqelm), field) = (elm); \
  140. } while (0)
  141. #define STAILQ_INSERT_HEAD(head, elm, field) do { \
  142. if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
  143. (head)->stqh_last = &STAILQ_NEXT((elm), field); \
  144. STAILQ_FIRST((head)) = (elm); \
  145. } while (0)
  146. #define STAILQ_INSERT_TAIL(head, elm, field) do { \
  147. STAILQ_NEXT((elm), field) = NULL; \
  148. *(head)->stqh_last = (elm); \
  149. (head)->stqh_last = &STAILQ_NEXT((elm), field); \
  150. } while (0)
  151. #define STAILQ_LAST(head, type, field) \
  152. (STAILQ_EMPTY((head)) ? \
  153. NULL : \
  154. ((struct type *)(void *) \
  155. ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
  156. #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
  157. #define STAILQ_REMOVE(head, elm, type, field) do { \
  158. QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \
  159. if (STAILQ_FIRST((head)) == (elm)) { \
  160. STAILQ_REMOVE_HEAD((head), field); \
  161. } \
  162. else { \
  163. struct type *curelm = STAILQ_FIRST((head)); \
  164. while (STAILQ_NEXT(curelm, field) != (elm)) \
  165. curelm = STAILQ_NEXT(curelm, field); \
  166. STAILQ_REMOVE_AFTER(head, curelm, field); \
  167. } \
  168. TRASHIT(*oldnext); \
  169. } while (0)
  170. #define STAILQ_REMOVE_HEAD(head, field) do { \
  171. if ((STAILQ_FIRST((head)) = \
  172. STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
  173. (head)->stqh_last = &STAILQ_FIRST((head)); \
  174. } while (0)
  175. #define STAILQ_REMOVE_AFTER(head, elm, field) do { \
  176. if ((STAILQ_NEXT(elm, field) = \
  177. STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
  178. (head)->stqh_last = &STAILQ_NEXT((elm), field); \
  179. } while (0)
  180. #define STAILQ_SWAP(head1, head2, type) do { \
  181. struct type *swap_first = STAILQ_FIRST(head1); \
  182. struct type **swap_last = (head1)->stqh_last; \
  183. STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
  184. (head1)->stqh_last = (head2)->stqh_last; \
  185. STAILQ_FIRST(head2) = swap_first; \
  186. (head2)->stqh_last = swap_last; \
  187. if (STAILQ_EMPTY(head1)) \
  188. (head1)->stqh_last = &STAILQ_FIRST(head1); \
  189. if (STAILQ_EMPTY(head2)) \
  190. (head2)->stqh_last = &STAILQ_FIRST(head2); \
  191. } while (0)
  192. #define STAILQ_INSERT_CHAIN_HEAD(head, elm_chead, elm_ctail, field) do { \
  193. if ((STAILQ_NEXT(elm_ctail, field) = STAILQ_FIRST(head)) == NULL ) { \
  194. (head)->stqh_last = &STAILQ_NEXT(elm_ctail, field); \
  195. } \
  196. STAILQ_FIRST(head) = (elm_chead); \
  197. } while (0)
  198. #endif /* !_SYS_QUEUE_H_ */