queue.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $
  31. */
  32. #ifndef _QUEUE_H_
  33. #define _QUEUE_H_
  34. /* The common BSD linked list queue macros are already defined here for ESP-IDF */
  35. #include <sys/queue.h>
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. /*
  40. * This file defines circular queues. The other types of data structures:
  41. * singly-linked lists, singly-linked tail queues, lists and tail queues
  42. * are used from sys/queue.h
  43. *
  44. * A singly-linked list is headed by a single forward pointer. The elements
  45. * are singly linked for minimum space and pointer manipulation overhead at
  46. * the expense of O(n) removal for arbitrary elements. New elements can be
  47. * added to the list after an existing element or at the head of the list.
  48. * Elements being removed from the head of the list should use the explicit
  49. * macro for this purpose for optimum efficiency. A singly-linked list may
  50. * only be traversed in the forward direction. Singly-linked lists are ideal
  51. * for applications with large datasets and few or no removals or for
  52. * implementing a LIFO queue.
  53. *
  54. * A singly-linked tail queue is headed by a pair of pointers, one to the
  55. * head of the list and the other to the tail of the list. The elements are
  56. * singly linked for minimum space and pointer manipulation overhead at the
  57. * expense of O(n) removal for arbitrary elements. New elements can be added
  58. * to the list after an existing element, at the head of the list, or at the
  59. * end of the list. Elements being removed from the head of the tail queue
  60. * should use the explicit macro for this purpose for optimum efficiency.
  61. * A singly-linked tail queue may only be traversed in the forward direction.
  62. * Singly-linked tail queues are ideal for applications with large datasets
  63. * and few or no removals or for implementing a FIFO queue.
  64. *
  65. * A list is headed by a single forward pointer (or an array of forward
  66. * pointers for a hash table header). The elements are doubly linked
  67. * so that an arbitrary element can be removed without a need to
  68. * traverse the list. New elements can be added to the list before
  69. * or after an existing element or at the head of the list. A list
  70. * may only be traversed in the forward direction.
  71. *
  72. * A tail queue is headed by a pair of pointers, one to the head of the
  73. * list and the other to the tail of the list. The elements are doubly
  74. * linked so that an arbitrary element can be removed without a need to
  75. * traverse the list. New elements can be added to the list before or
  76. * after an existing element, at the head of the list, or at the end of
  77. * the list. A tail queue may be traversed in either direction.
  78. *
  79. * A circle queue is headed by a pair of pointers, one to the head of the
  80. * list and the other to the tail of the list. The elements are doubly
  81. * linked so that an arbitrary element can be removed without a need to
  82. * traverse the list. New elements can be added to the list before or after
  83. * an existing element, at the head of the list, or at the end of the list.
  84. * A circle queue may be traversed in either direction, but has a more
  85. * complex end of list detection.
  86. *
  87. * For details on the use of these macros, see the queue(3) manual page.
  88. *
  89. *
  90. * SLIST LIST STAILQ TAILQ CIRCLEQ
  91. * _HEAD + + + + +
  92. * _HEAD_INITIALIZER + + + + +
  93. * _ENTRY + + + + +
  94. * _INIT + + + + +
  95. * _EMPTY + + + + +
  96. * _FIRST + + + + +
  97. * _NEXT + + + + +
  98. * _PREV - - - + +
  99. * _LAST - - + + +
  100. * _FOREACH + + + + +
  101. * _FOREACH_REVERSE - - - + +
  102. * _INSERT_HEAD + + + + +
  103. * _INSERT_BEFORE - + - + +
  104. * _INSERT_AFTER + + + + +
  105. * _INSERT_TAIL - - + + +
  106. * _REMOVE_HEAD + - + - -
  107. * _REMOVE + + + + +
  108. *
  109. */
  110. /*
  111. * Circular queue declarations.
  112. */
  113. #define CIRCLEQ_HEAD(name, type) \
  114. struct name { \
  115. struct type *cqh_first; /* first element */ \
  116. struct type *cqh_last; /* last element */ \
  117. }
  118. #define CIRCLEQ_HEAD_INITIALIZER(head) \
  119. { (void *)&(head), (void *)&(head) }
  120. #define CIRCLEQ_ENTRY(type) \
  121. struct { \
  122. struct type *cqe_next; /* next element */ \
  123. struct type *cqe_prev; /* previous element */ \
  124. }
  125. /*
  126. * Circular queue functions.
  127. */
  128. #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
  129. #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
  130. #define CIRCLEQ_FOREACH(var, head, field) \
  131. for ((var) = CIRCLEQ_FIRST((head)); \
  132. (var) != (void *)(head) || ((var) = NULL); \
  133. (var) = CIRCLEQ_NEXT((var), field))
  134. #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
  135. for ((var) = CIRCLEQ_LAST((head)); \
  136. (var) != (void *)(head) || ((var) = NULL); \
  137. (var) = CIRCLEQ_PREV((var), field))
  138. #define CIRCLEQ_INIT(head) do { \
  139. CIRCLEQ_FIRST((head)) = (void *)(head); \
  140. CIRCLEQ_LAST((head)) = (void *)(head); \
  141. } while (0)
  142. #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
  143. CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
  144. CIRCLEQ_PREV((elm), field) = (listelm); \
  145. if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
  146. CIRCLEQ_LAST((head)) = (elm); \
  147. else \
  148. CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
  149. CIRCLEQ_NEXT((listelm), field) = (elm); \
  150. } while (0)
  151. #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
  152. CIRCLEQ_NEXT((elm), field) = (listelm); \
  153. CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
  154. if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
  155. CIRCLEQ_FIRST((head)) = (elm); \
  156. else \
  157. CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
  158. CIRCLEQ_PREV((listelm), field) = (elm); \
  159. } while (0)
  160. #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
  161. CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
  162. CIRCLEQ_PREV((elm), field) = (void *)(head); \
  163. if (CIRCLEQ_LAST((head)) == (void *)(head)) \
  164. CIRCLEQ_LAST((head)) = (elm); \
  165. else \
  166. CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
  167. CIRCLEQ_FIRST((head)) = (elm); \
  168. } while (0)
  169. #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
  170. CIRCLEQ_NEXT((elm), field) = (void *)(head); \
  171. CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
  172. if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
  173. CIRCLEQ_FIRST((head)) = (elm); \
  174. else \
  175. CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
  176. CIRCLEQ_LAST((head)) = (elm); \
  177. } while (0)
  178. #define CIRCLEQ_LAST(head) ((head)->cqh_last)
  179. #define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
  180. #define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
  181. #define CIRCLEQ_REMOVE(head, elm, field) do { \
  182. if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
  183. CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
  184. else \
  185. CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
  186. CIRCLEQ_PREV((elm), field); \
  187. if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
  188. CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
  189. else \
  190. CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
  191. CIRCLEQ_NEXT((elm), field); \
  192. } while (0)
  193. #ifdef __cplusplus
  194. }
  195. #endif
  196. #endif /* !_SYS_QUEUE_H_ */