lqueue.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* Licensed under BSD-MIT - see LICENSE file for details */
  2. #ifndef CCAN_LQUEUE_H
  3. #define CCAN_LQUEUE_H
  4. #include <stdbool.h>
  5. #include <stdio.h>
  6. #include <assert.h>
  7. #include <ccan/container_of/container_of.h>
  8. /**
  9. * struct lqueue_link - a queue link
  10. * @next: next entry, or front of queue, if this is the back
  11. *
  12. * This is used as a link within a queue entry.
  13. *
  14. * Example:
  15. * struct waiter {
  16. * char *name;
  17. * struct lqueue_link ql;
  18. * };
  19. */
  20. struct lqueue_link {
  21. struct lqueue_link *next;
  22. };
  23. /**
  24. * struct lqueue - the head of a queue
  25. * @b: the back of the queue (NULL if empty)
  26. */
  27. struct lqueue {
  28. struct lqueue_link *back;
  29. };
  30. /**
  31. * LQUEUE - define and initialize an empty queue
  32. * @name: the name of the lqueue.
  33. *
  34. * The LQUEUE macro defines an lqueue and initializes it to an empty
  35. * queue. It can be prepended by "static" to define a static lqueue.
  36. *
  37. * See also:
  38. * lqueue_init()
  39. *
  40. * Example:
  41. * LQUEUE(my_queue);
  42. *
  43. * assert(lqueue_empty(&my_queue));
  44. */
  45. #define LQUEUE(name) \
  46. struct lqueue name = { NULL, }
  47. /**
  48. * lqueue_init - initialize a queue
  49. * @h: the lqueue to set to an empty queue
  50. *
  51. * Example:
  52. * struct lqueue *qp = malloc(sizeof(*qp));
  53. * lqueue_init(qp);
  54. */
  55. static inline void lqueue_init(struct lqueue *q)
  56. {
  57. q->back = NULL;
  58. }
  59. /**
  60. * lqueue_empty - is a queue empty?
  61. * @q: the queue
  62. *
  63. * If the queue is empty, returns true.
  64. *
  65. * Example:
  66. * assert(lqueue_empty(qp));
  67. */
  68. static inline bool lqueue_empty(const struct lqueue *q)
  69. {
  70. return (q->back == NULL);
  71. }
  72. /**
  73. * lqueue_entry - convert an lqueue_link back into the structure containing it.
  74. * @e: the lqueue_link
  75. * @type: the type of the entry
  76. * @member: the lqueue_link member of the type
  77. *
  78. * Example:
  79. * struct waiter {
  80. * char *name;
  81. * struct lqueue_link ql;
  82. * } w;
  83. * assert(lqueue_entry(&w.ql, struct waiter, ql) == &w);
  84. */
  85. #define lqueue_entry(n, type, member) container_of_or_null(n, type, member)
  86. /**
  87. * lqueue_front - get front entry in a queue
  88. * @q: the queue
  89. * @type: the type of queue entries
  90. * @member: the lqueue_link entry
  91. *
  92. * If the queue is empty, returns NULL.
  93. *
  94. * Example:
  95. * struct waiter *f;
  96. *
  97. * f = lqueue_front(qp, struct waiter, ql);
  98. * assert(lqueue_dequeue(qp, struct waiter, ql) == f);
  99. */
  100. #define lqueue_front(q, type, member) \
  101. lqueue_entry(lqueue_front_((q)), type, member)
  102. static inline struct lqueue_link *lqueue_front_(const struct lqueue *q)
  103. {
  104. if (!q->back)
  105. return NULL;
  106. else
  107. return q->back->next;
  108. }
  109. /**
  110. * lqueue_back - get back entry in a queue
  111. * @q: the queue
  112. * @type: the type of queue entries
  113. * @member: the lqueue_link entry
  114. *
  115. * If the queue is empty, returns NULL.
  116. *
  117. * Example:
  118. * struct waiter b;
  119. *
  120. * lqueue_enqueue(qp, &b, ql);
  121. * assert(lqueue_back(qp, struct waiter, ql) == &b);
  122. */
  123. #define lqueue_back(q, type, member) \
  124. lqueue_entry(lqueue_back_((q)), type, member)
  125. static inline struct lqueue_link *lqueue_back_(const struct lqueue *q)
  126. {
  127. return q->back;
  128. }
  129. /**
  130. * lqueue_enqueue - add an entry to the back of a queue
  131. * @q: the queue to add the node to
  132. * @e: the item to enqueue
  133. * @member: the lqueue_link field of *e
  134. *
  135. * The lqueue_link does not need to be initialized; it will be overwritten.
  136. */
  137. #define lqueue_enqueue(q, e, member) \
  138. lqueue_enqueue_((q), &((e)->member))
  139. static inline void lqueue_enqueue_(struct lqueue *q, struct lqueue_link *e)
  140. {
  141. if (lqueue_empty(q)) {
  142. /* New entry will be both front and back of queue */
  143. e->next = e;
  144. q->back = e;
  145. } else {
  146. e->next = lqueue_front_(q);
  147. q->back->next = e;
  148. q->back = e;
  149. }
  150. }
  151. /**
  152. * lqueue_dequeue - remove and return the entry from the front of the queue
  153. * @q: the queue
  154. * @type: the type of queue entries
  155. * @member: the lqueue_link field of @type
  156. *
  157. * Note that this leaves the returned entry's link in an undefined
  158. * state; it can be added to another queue, but not deleted again.
  159. */
  160. #define lqueue_dequeue(q, type, member) \
  161. lqueue_entry(lqueue_dequeue_((q)), type, member)
  162. static inline struct lqueue_link *lqueue_dequeue_(struct lqueue *q)
  163. {
  164. struct lqueue_link *front;
  165. if (lqueue_empty(q))
  166. return NULL;
  167. front = lqueue_front_(q);
  168. if (front == lqueue_back_(q)) {
  169. assert(front->next == front);
  170. q->back = NULL;
  171. } else {
  172. q->back->next = front->next;
  173. }
  174. return front;
  175. }
  176. #endif /* CCAN_LQUEUE_H */