list.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /*
  2. * Copyright (c) 2009, 2010 Richard Braun.
  3. * 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 rblist of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this rblist of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. *
  25. *
  26. * Simple doubly-linked rblist.
  27. */
  28. #ifndef _KERN_rblist_H
  29. #define _KERN_rblist_H
  30. #include <stddef.h>
  31. #include <sys/types.h>
  32. #include <kern/macros.h>
  33. /*
  34. * Structure used as both head and node.
  35. *
  36. * This implementation relies on using the same type for both heads and nodes.
  37. *
  38. * It is recommended to encode the use of struct rblist variables in their names,
  39. * e.g. struct rblist free_rblist or struct rblist free_objects is a good hint for a
  40. * rblist of free objects. A declaration like struct rblist free_node clearly
  41. * indicates it is used as part of a node in the free rblist.
  42. */
  43. struct rblist {
  44. struct rblist *prev;
  45. struct rblist *next;
  46. };
  47. #define list rblist
  48. //undef if confliction
  49. /*
  50. * Static rblist initializer.
  51. */
  52. #define rblist_INITIALIZER(rblist) { &(rblist), &(rblist) }
  53. /*
  54. * Initialize a rblist.
  55. */
  56. static inline void rblist_init(struct rblist *rblist)
  57. {
  58. rblist->prev = rblist;
  59. rblist->next = rblist;
  60. }
  61. /*
  62. * Initialize a rblist node.
  63. *
  64. * An entry is in no rblist when its node members point to NULL.
  65. */
  66. static inline void rblist_node_init(struct rblist *node)
  67. {
  68. node->prev = NULL;
  69. node->next = NULL;
  70. }
  71. /*
  72. * Return true if node is in no rblist.
  73. */
  74. static inline int rblist_node_unlinked(const struct rblist *node)
  75. {
  76. return node->prev == NULL;
  77. }
  78. /*
  79. * Macro that evaluates to the address of the structure containing the
  80. * given node based on the given type and member.
  81. */
  82. #define rblist_entry(node, type, member) structof(node, type, member)
  83. /*
  84. * Return the first node of a rblist.
  85. */
  86. static inline struct rblist * rblist_first(const struct rblist *rblist)
  87. {
  88. return rblist->next;
  89. }
  90. /*
  91. * Return the last node of a rblist.
  92. */
  93. static inline struct rblist * rblist_last(const struct rblist *rblist)
  94. {
  95. return rblist->prev;
  96. }
  97. /*
  98. * Return the node next to the given node.
  99. */
  100. static inline struct rblist * rblist_next(const struct rblist *node)
  101. {
  102. return node->next;
  103. }
  104. /*
  105. * Return the node previous to the given node.
  106. */
  107. static inline struct rblist * rblist_prev(const struct rblist *node)
  108. {
  109. return node->prev;
  110. }
  111. /*
  112. * Get the first entry of a rblist.
  113. */
  114. #define rblist_first_entry(rblist, type, member) \
  115. rblist_entry(rblist_first(rblist), type, member)
  116. /*
  117. * Get the last entry of a rblist.
  118. */
  119. #define rblist_last_entry(rblist, type, member) \
  120. rblist_entry(rblist_last(rblist), type, member)
  121. /*
  122. * Return true if node is after the last or before the first node of the rblist.
  123. */
  124. static inline int rblist_end(const struct rblist *rblist, const struct rblist *node)
  125. {
  126. return rblist == node;
  127. }
  128. /*
  129. * Return true if rblist is empty.
  130. */
  131. static inline int rblist_empty(const struct rblist *rblist)
  132. {
  133. return rblist == rblist->next;
  134. }
  135. /*
  136. * Return true if rblist contains exactly one node.
  137. */
  138. static inline int rblist_singular(const struct rblist *rblist)
  139. {
  140. return (rblist != rblist->next) && (rblist->next == rblist->prev);
  141. }
  142. /*
  143. * Split rblist2 by moving its nodes up to (but not including) the given
  144. * node into rblist1 (which can be in a stale state).
  145. *
  146. * If rblist2 is empty, or node is rblist2 or rblist2->next, nothing is done.
  147. */
  148. static inline void rblist_split(struct rblist *rblist1, struct rblist *rblist2,
  149. struct rblist *node)
  150. {
  151. if (rblist_empty(rblist2) || (rblist2->next == node) || rblist_end(rblist2, node))
  152. return;
  153. rblist1->next = rblist2->next;
  154. rblist1->next->prev = rblist1;
  155. rblist1->prev = node->prev;
  156. node->prev->next = rblist1;
  157. rblist2->next = node;
  158. node->prev = rblist2;
  159. }
  160. /*
  161. * Append the nodes of rblist2 at the end of rblist1.
  162. *
  163. * After completion, rblist2 is stale.
  164. */
  165. static inline void rblist_concat(struct rblist *rblist1, const struct rblist *rblist2)
  166. {
  167. struct rblist *last1, *first2, *last2;
  168. if (rblist_empty(rblist2))
  169. return;
  170. last1 = rblist1->prev;
  171. first2 = rblist2->next;
  172. last2 = rblist2->prev;
  173. last1->next = first2;
  174. first2->prev = last1;
  175. last2->next = rblist1;
  176. rblist1->prev = last2;
  177. }
  178. /*
  179. * Set the new head of a rblist.
  180. *
  181. * This function is an optimized version of :
  182. * rblist_init(&new_rblist);
  183. * rblist_concat(&new_rblist, &old_rblist);
  184. *
  185. * After completion, old_head is stale.
  186. */
  187. static inline void rblist_set_head(struct rblist *new_head,
  188. const struct rblist *old_head)
  189. {
  190. if (rblist_empty(old_head)) {
  191. rblist_init(new_head);
  192. return;
  193. }
  194. *new_head = *old_head;
  195. new_head->next->prev = new_head;
  196. new_head->prev->next = new_head;
  197. }
  198. /*
  199. * Add a node between two nodes.
  200. */
  201. static inline void rblist_add(struct rblist *prev, struct rblist *next,
  202. struct rblist *node)
  203. {
  204. next->prev = node;
  205. node->next = next;
  206. prev->next = node;
  207. node->prev = prev;
  208. }
  209. /*
  210. * Insert a node at the head of a rblist.
  211. */
  212. static inline void rblist_insert_head(struct rblist *rblist, struct rblist *node)
  213. {
  214. rblist_add(rblist, rblist->next, node);
  215. }
  216. /*
  217. * Insert a node at the tail of a rblist.
  218. */
  219. static inline void rblist_insert_tail(struct rblist *rblist, struct rblist *node)
  220. {
  221. rblist_add(rblist->prev, rblist, node);
  222. }
  223. /*
  224. * Insert a node before another node.
  225. */
  226. static inline void rblist_insert_before(struct rblist *next, struct rblist *node)
  227. {
  228. rblist_add(next->prev, next, node);
  229. }
  230. /*
  231. * Insert a node after another node.
  232. */
  233. static inline void rblist_insert_after(struct rblist *prev, struct rblist *node)
  234. {
  235. rblist_add(prev, prev->next, node);
  236. }
  237. /*
  238. * Remove a node from a rblist.
  239. *
  240. * After completion, the node is stale.
  241. */
  242. static inline void rblist_remove(struct rblist *node)
  243. {
  244. node->prev->next = node->next;
  245. node->next->prev = node->prev;
  246. }
  247. /*
  248. * Forge a loop to process all nodes of a rblist.
  249. *
  250. * The node must not be altered during the loop.
  251. */
  252. #define rblist_for_each(rblist, node) \
  253. for (node = rblist_first(rblist); \
  254. !rblist_end(rblist, node); \
  255. node = rblist_next(node))
  256. /*
  257. * Forge a loop to process all nodes of a rblist.
  258. */
  259. #define rblist_for_each_safe(rblist, node, tmp) \
  260. for (node = rblist_first(rblist), tmp = rblist_next(node); \
  261. !rblist_end(rblist, node); \
  262. node = tmp, tmp = rblist_next(node))
  263. /*
  264. * Version of rblist_for_each() that processes nodes backward.
  265. */
  266. #define rblist_for_each_reverse(rblist, node) \
  267. for (node = rblist_last(rblist); \
  268. !rblist_end(rblist, node); \
  269. node = rblist_prev(node))
  270. /*
  271. * Version of rblist_for_each_safe() that processes nodes backward.
  272. */
  273. #define rblist_for_each_reverse_safe(rblist, node, tmp) \
  274. for (node = rblist_last(rblist), tmp = rblist_prev(node); \
  275. !rblist_end(rblist, node); \
  276. node = tmp, tmp = rblist_prev(node))
  277. /*
  278. * Forge a loop to process all entries of a rblist.
  279. *
  280. * The entry node must not be altered during the loop.
  281. */
  282. #define rblist_for_each_entry(rblist, entry, member) \
  283. for (entry = rblist_entry(rblist_first(rblist), typeof(*entry), member); \
  284. !rblist_end(rblist, &entry->member); \
  285. entry = rblist_entry(rblist_next(&entry->member), typeof(*entry), \
  286. member))
  287. /*
  288. * Forge a loop to process all entries of a rblist.
  289. */
  290. #define rblist_for_each_entry_safe(rblist, entry, tmp, member) \
  291. for (entry = rblist_entry(rblist_first(rblist), typeof(*entry), member), \
  292. tmp = rblist_entry(rblist_next(&entry->member), typeof(*entry), \
  293. member); \
  294. !rblist_end(rblist, &entry->member); \
  295. entry = tmp, tmp = rblist_entry(rblist_next(&entry->member), \
  296. typeof(*entry), member))
  297. /*
  298. * Version of rblist_for_each_entry() that processes entries backward.
  299. */
  300. #define rblist_for_each_entry_reverse(rblist, entry, member) \
  301. for (entry = rblist_entry(rblist_last(rblist), typeof(*entry), member); \
  302. !rblist_end(rblist, &entry->member); \
  303. entry = rblist_entry(rblist_prev(&entry->member), typeof(*entry), \
  304. member))
  305. /*
  306. * Version of rblist_for_each_entry_safe() that processes entries backward.
  307. */
  308. #define rblist_for_each_entry_reverse_safe(rblist, entry, tmp, member) \
  309. for (entry = rblist_entry(rblist_last(rblist), typeof(*entry), member), \
  310. tmp = rblist_entry(rblist_prev(&entry->member), typeof(*entry), \
  311. member); \
  312. !rblist_end(rblist, &entry->member); \
  313. entry = tmp, tmp = rblist_entry(rblist_prev(&entry->member), \
  314. typeof(*entry), member))
  315. #endif /* _KERN_rblist_H */