You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

list.h 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. #ifndef _IPXE_LIST_H
  2. #define _IPXE_LIST_H
  3. /** @file
  4. *
  5. * Linked lists
  6. *
  7. * This linked list handling code is based on the Linux kernel's
  8. * list.h.
  9. */
  10. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  11. #include <stddef.h>
  12. #include <assert.h>
  13. /** A doubly-linked list entry (or list head) */
  14. struct list_head {
  15. /** Next list entry */
  16. struct list_head *next;
  17. /** Previous list entry */
  18. struct list_head *prev;
  19. };
  20. /**
  21. * Initialise a static list head
  22. *
  23. * @v list List head
  24. */
  25. #define LIST_HEAD_INIT( list ) { &(list), &(list) }
  26. /**
  27. * Declare a static list head
  28. *
  29. * @v list List head
  30. */
  31. #define LIST_HEAD( list ) \
  32. struct list_head list = LIST_HEAD_INIT ( list )
  33. /**
  34. * Initialise a list head
  35. *
  36. * @v list List head
  37. */
  38. #define INIT_LIST_HEAD( list ) do { \
  39. (list)->next = (list); \
  40. (list)->prev = (list); \
  41. } while ( 0 )
  42. /**
  43. * Check a list entry or list head is valid
  44. *
  45. * @v list List entry or head
  46. */
  47. #define list_check( list ) ( { \
  48. assert ( (list) != NULL ); \
  49. assert ( (list)->prev != NULL ); \
  50. assert ( (list)->next != NULL ); \
  51. assert ( (list)->next->prev == (list) ); \
  52. assert ( (list)->prev->next == (list) ); \
  53. } )
  54. /**
  55. * Add a new entry to the head of a list
  56. *
  57. * @v new New entry to be added
  58. * @v head List head, or entry after which to add the new entry
  59. */
  60. #define list_add( new, head ) do { \
  61. list_check ( (head) ); \
  62. extern_list_add ( (new), (head) ); \
  63. list_check ( (head) ); \
  64. list_check ( (new) ); \
  65. } while ( 0 )
  66. static inline void inline_list_add ( struct list_head *new,
  67. struct list_head *head ) {
  68. struct list_head *prev = head;
  69. struct list_head *next = head->next;
  70. next->prev = (new);
  71. (new)->next = next;
  72. (new)->prev = prev;
  73. prev->next = (new);
  74. }
  75. extern void extern_list_add ( struct list_head *new,
  76. struct list_head *head );
  77. /**
  78. * Add a new entry to the tail of a list
  79. *
  80. * @v new New entry to be added
  81. * @v head List head, or entry before which to add the new entry
  82. */
  83. #define list_add_tail( new, head ) do { \
  84. list_check ( (head) ); \
  85. extern_list_add_tail ( (new), (head) ); \
  86. list_check ( (head) ); \
  87. list_check ( (new) ); \
  88. } while ( 0 )
  89. static inline void inline_list_add_tail ( struct list_head *new,
  90. struct list_head *head ) {
  91. struct list_head *prev = head->prev;
  92. struct list_head *next = head;
  93. next->prev = (new);
  94. (new)->next = next;
  95. (new)->prev = prev;
  96. prev->next = (new);
  97. }
  98. extern void extern_list_add_tail ( struct list_head *new,
  99. struct list_head *head );
  100. /**
  101. * Delete an entry from a list
  102. *
  103. * @v list List entry
  104. *
  105. * Note that list_empty() on entry does not return true after this;
  106. * the entry is in an undefined state.
  107. */
  108. #define list_del( list ) do { \
  109. list_check ( (list) ); \
  110. inline_list_del ( (list) ); \
  111. } while ( 0 )
  112. static inline void inline_list_del ( struct list_head *list ) {
  113. struct list_head *next = (list)->next;
  114. struct list_head *prev = (list)->prev;
  115. next->prev = prev;
  116. prev->next = next;
  117. }
  118. extern void extern_list_del ( struct list_head *list );
  119. /**
  120. * Test whether a list is empty
  121. *
  122. * @v list List head
  123. */
  124. #define list_empty( list ) ( { \
  125. list_check ( (list) ); \
  126. inline_list_empty ( (list) ); } )
  127. static inline int inline_list_empty ( const struct list_head *list ) {
  128. return ( list->next == list );
  129. }
  130. extern int extern_list_empty ( const struct list_head *list );
  131. /**
  132. * Test whether a list has just one entry
  133. *
  134. * @v list List to test
  135. */
  136. #define list_is_singular( list ) ( { \
  137. list_check ( (list) ); \
  138. inline_list_is_singular ( (list) ); } )
  139. static inline int inline_list_is_singular ( const struct list_head *list ) {
  140. return ( ( ! list_empty ( list ) ) && ( list->next == list->prev ) );
  141. }
  142. extern int extern_list_is_singular ( const struct list_head *list );
  143. /**
  144. * Test whether an entry is the last entry in list
  145. *
  146. * @v list List entry to test
  147. * @v head List head
  148. */
  149. #define list_is_last( list, head ) ( { \
  150. list_check ( (list) ); \
  151. list_check ( (head) ); \
  152. inline_list_is_last ( (list), (head) ); } )
  153. static inline int inline_list_is_last ( const struct list_head *list,
  154. const struct list_head *head ) {
  155. return ( list->next == head );
  156. }
  157. extern int extern_list_is_last ( const struct list_head *list,
  158. const struct list_head *head );
  159. /**
  160. * Cut a list into two
  161. *
  162. * @v new A new list to contain all removed entries
  163. * @v list An existing list
  164. * @v entry An entry within the existing list
  165. *
  166. * All entries from @c list up to and including @c entry are moved to
  167. * @c new, which should be an empty list. @c entry may be equal to @c
  168. * list, in which case no entries are moved.
  169. */
  170. #define list_cut_position( new, list, entry ) do { \
  171. list_check ( (new) ); \
  172. assert ( list_empty ( (new) ) ); \
  173. list_check ( (list) ); \
  174. list_check ( (entry) ); \
  175. extern_list_cut_position ( (new), (list), (entry) ); \
  176. } while ( 0 )
  177. static inline void inline_list_cut_position ( struct list_head *new,
  178. struct list_head *list,
  179. struct list_head *entry ) {
  180. struct list_head *first = entry->next;
  181. if ( list != entry ) {
  182. new->next = list->next;
  183. new->next->prev = new;
  184. new->prev = entry;
  185. new->prev->next = new;
  186. list->next = first;
  187. list->next->prev = list;
  188. }
  189. }
  190. extern void extern_list_cut_position ( struct list_head *new,
  191. struct list_head *list,
  192. struct list_head *entry );
  193. /**
  194. * Move all entries from one list into another list
  195. *
  196. * @v list List of entries to add
  197. * @v entry Entry after which to add the new entries
  198. *
  199. * All entries from @c list are inserted after @c entry. Note that @c
  200. * list is left in an undefined state; use @c list_splice_init() if
  201. * you want @c list to become an empty list.
  202. */
  203. #define list_splice( list, entry ) do { \
  204. list_check ( (list) ); \
  205. list_check ( (entry) ); \
  206. extern_list_splice ( (list), (entry) ); \
  207. } while ( 0 )
  208. static inline void inline_list_splice ( const struct list_head *list,
  209. struct list_head *entry ) {
  210. struct list_head *first = list->next;
  211. struct list_head *last = list->prev;
  212. if ( ! list_empty ( list ) ) {
  213. last->next = entry->next;
  214. last->next->prev = last;
  215. first->prev = entry;
  216. first->prev->next = first;
  217. }
  218. }
  219. extern void extern_list_splice ( const struct list_head *list,
  220. struct list_head *entry );
  221. /**
  222. * Move all entries from one list into another list
  223. *
  224. * @v list List of entries to add
  225. * @v entry Entry before which to add the new entries
  226. *
  227. * All entries from @c list are inserted before @c entry. Note that @c
  228. * list is left in an undefined state; use @c list_splice_tail_init() if
  229. * you want @c list to become an empty list.
  230. */
  231. #define list_splice_tail( list, entry ) do { \
  232. list_check ( (list) ); \
  233. list_check ( (entry) ); \
  234. extern_list_splice_tail ( (list), (entry) ); \
  235. } while ( 0 )
  236. static inline void inline_list_splice_tail ( const struct list_head *list,
  237. struct list_head *entry ) {
  238. struct list_head *first = list->next;
  239. struct list_head *last = list->prev;
  240. if ( ! list_empty ( list ) ) {
  241. first->prev = entry->prev;
  242. first->prev->next = first;
  243. last->next = entry;
  244. last->next->prev = last;
  245. }
  246. }
  247. extern void extern_list_splice_tail ( const struct list_head *list,
  248. struct list_head *entry );
  249. /**
  250. * Move all entries from one list into another list and reinitialise empty list
  251. *
  252. * @v list List of entries to add
  253. * @v entry Entry after which to add the new entries
  254. *
  255. * All entries from @c list are inserted after @c entry.
  256. */
  257. #define list_splice_init( list, entry ) do { \
  258. list_check ( (list) ); \
  259. list_check ( (entry) ); \
  260. extern_list_splice_init ( (list), (entry) ); \
  261. } while ( 0 )
  262. static inline void inline_list_splice_init ( struct list_head *list,
  263. struct list_head *entry ) {
  264. list_splice ( list, entry );
  265. INIT_LIST_HEAD ( list );
  266. }
  267. extern void extern_list_splice_init ( struct list_head *list,
  268. struct list_head *entry );
  269. /**
  270. * Move all entries from one list into another list and reinitialise empty list
  271. *
  272. * @v list List of entries to add
  273. * @v entry Entry before which to add the new entries
  274. *
  275. * All entries from @c list are inserted before @c entry.
  276. */
  277. #define list_splice_tail_init( list, entry ) do { \
  278. list_check ( (list) ); \
  279. list_check ( (entry) ); \
  280. extern_list_splice_tail_init ( (list), (entry) ); \
  281. } while ( 0 )
  282. static inline void inline_list_splice_tail_init ( struct list_head *list,
  283. struct list_head *entry ) {
  284. list_splice_tail ( list, entry );
  285. INIT_LIST_HEAD ( list );
  286. }
  287. extern void extern_list_splice_tail_init ( struct list_head *list,
  288. struct list_head *entry );
  289. /**
  290. * Get the container of a list entry
  291. *
  292. * @v list List entry
  293. * @v type Containing type
  294. * @v member Name of list field within containing type
  295. * @ret container Containing object
  296. */
  297. #define list_entry( list, type, member ) ( { \
  298. list_check ( (list) ); \
  299. container_of ( list, type, member ); } )
  300. /**
  301. * Get the container of the first entry in a list
  302. *
  303. * @v list List head
  304. * @v type Containing type
  305. * @v member Name of list field within containing type
  306. * @ret first First list entry, or NULL
  307. */
  308. #define list_first_entry( list, type, member ) \
  309. ( list_empty ( (list) ) ? \
  310. ( type * ) NULL : \
  311. list_entry ( (list)->next, type, member ) )
  312. /**
  313. * Get the container of the last entry in a list
  314. *
  315. * @v list List head
  316. * @v type Containing type
  317. * @v member Name of list field within containing type
  318. * @ret first First list entry, or NULL
  319. */
  320. #define list_last_entry( list, type, member ) \
  321. ( list_empty ( (list) ) ? \
  322. ( type * ) NULL : \
  323. list_entry ( (list)->prev, type, member ) )
  324. /**
  325. * Get the container of the next entry in a list
  326. *
  327. * @v pos Current list entry
  328. * @v head List head
  329. * @v member Name of list field within iterator's type
  330. * @ret next Next list entry, or NULL at end of list
  331. */
  332. #define list_next_entry( pos, head, member ) ( { \
  333. typeof (pos) next = list_entry ( (pos)->member.next, \
  334. typeof ( *(pos) ), \
  335. member ); \
  336. ( ( &next->member == (head) ) ? NULL : next ); } )
  337. /**
  338. * Get the container of the previous entry in a list
  339. *
  340. * @v pos Current list entry
  341. * @v head List head
  342. * @v member Name of list field within iterator's type
  343. * @ret next Next list entry, or NULL at end of list
  344. */
  345. #define list_prev_entry( pos, head, member ) ( { \
  346. typeof (pos) prev = list_entry ( (pos)->member.prev, \
  347. typeof ( *(pos) ), \
  348. member ); \
  349. ( ( &prev->member == (head) ) ? NULL : prev ); } )
  350. /**
  351. * Test if entry is first in a list
  352. *
  353. * @v entry List entry
  354. * @v head List head
  355. * @v member Name of list field within iterator's type
  356. * @ret is_first Entry is first in the list
  357. */
  358. #define list_is_first_entry( entry, head, member ) \
  359. ( (head)->next == &(entry)->member )
  360. /**
  361. * Test if entry is last in a list
  362. *
  363. * @v entry List entry
  364. * @v head List head
  365. * @v member Name of list field within iterator's type
  366. * @ret is_last Entry is last in the list
  367. */
  368. #define list_is_last_entry( entry, head, member ) \
  369. ( (head)->prev == &(entry)->member )
  370. /**
  371. * Iterate over a list
  372. *
  373. * @v pos Iterator
  374. * @v head List head
  375. */
  376. #define list_for_each( pos, head ) \
  377. for ( list_check ( (head) ), \
  378. pos = (head)->next; \
  379. pos != (head); \
  380. pos = (pos)->next )
  381. /**
  382. * Iterate over entries in a list
  383. *
  384. * @v pos Iterator
  385. * @v head List head
  386. * @v member Name of list field within iterator's type
  387. */
  388. #define list_for_each_entry( pos, head, member ) \
  389. for ( list_check ( (head) ), \
  390. pos = list_entry ( (head)->next, typeof ( *pos ), member ); \
  391. &pos->member != (head); \
  392. pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
  393. /**
  394. * Iterate over entries in a list in reverse order
  395. *
  396. * @v pos Iterator
  397. * @v head List head
  398. * @v member Name of list field within iterator's type
  399. */
  400. #define list_for_each_entry_reverse( pos, head, member ) \
  401. for ( list_check ( (head) ), \
  402. pos = list_entry ( (head)->prev, typeof ( *pos ), member ); \
  403. &pos->member != (head); \
  404. pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) )
  405. /**
  406. * Iterate over entries in a list, safe against deletion of the current entry
  407. *
  408. * @v pos Iterator
  409. * @v tmp Temporary value (of same type as iterator)
  410. * @v head List head
  411. * @v member Name of list field within iterator's type
  412. */
  413. #define list_for_each_entry_safe( pos, tmp, head, member ) \
  414. for ( list_check ( (head) ), \
  415. pos = list_entry ( (head)->next, typeof ( *pos ), member ), \
  416. tmp = list_entry ( pos->member.next, typeof ( *tmp ), member ); \
  417. &pos->member != (head); \
  418. pos = tmp, \
  419. tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) )
  420. /**
  421. * Iterate over entries in a list, starting after current position
  422. *
  423. * @v pos Iterator
  424. * @v head List head
  425. * @v member Name of list field within iterator's type
  426. */
  427. #define list_for_each_entry_continue( pos, head, member ) \
  428. for ( list_check ( (head) ), \
  429. pos = list_entry ( pos->member.next, typeof ( *pos ), member ); \
  430. &pos->member != (head); \
  431. pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
  432. /**
  433. * Iterate over entries in a list in reverse, starting after current position
  434. *
  435. * @v pos Iterator
  436. * @v head List head
  437. * @v member Name of list field within iterator's type
  438. */
  439. #define list_for_each_entry_continue_reverse( pos, head, member ) \
  440. for ( list_check ( (head) ), \
  441. pos = list_entry ( pos->member.prev, typeof ( *pos ), member ); \
  442. &pos->member != (head); \
  443. pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) )
  444. /**
  445. * Test if list contains a specified entry
  446. *
  447. * @v entry Entry
  448. * @v head List head
  449. * @ret present List contains specified entry
  450. */
  451. #define list_contains( entry, head ) ( { \
  452. list_check ( (head) ); \
  453. list_check ( (entry) ); \
  454. extern_list_contains ( (entry), (head) ); } )
  455. static inline int inline_list_contains ( struct list_head *entry,
  456. struct list_head *head ) {
  457. struct list_head *tmp;
  458. list_for_each ( tmp, head ) {
  459. if ( tmp == entry )
  460. return 1;
  461. }
  462. return 0;
  463. }
  464. extern int extern_list_contains ( struct list_head *entry,
  465. struct list_head *head );
  466. /**
  467. * Test if list contains a specified entry
  468. *
  469. * @v entry Entry
  470. * @v head List head
  471. * @ret present List contains specified entry
  472. */
  473. #define list_contains_entry( entry, head, member ) \
  474. list_contains ( &(entry)->member, (head) )
  475. /**
  476. * Check list contains a specified entry
  477. *
  478. * @v entry Entry
  479. * @v head List head
  480. * @v member Name of list field within iterator's type
  481. */
  482. #define list_check_contains_entry( entry, head, member ) do { \
  483. assert ( list_contains_entry ( (entry), (head), member ) ); \
  484. } while ( 0 )
  485. #endif /* _IPXE_LIST_H */