queue.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  1. /*++
  2. Copyright (c) 2017 Minoca Corp.
  3. This file is licensed under the terms of the GNU Lesser General Public
  4. License version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details.
  6. Module Name:
  7. queue.h
  8. Abstract:
  9. This header contains definitions and macros for various queue structures.
  10. Author:
  11. Chris Stevens 25-Jan-2017
  12. --*/
  13. #ifndef _QUEUE_H
  14. #define _QUEUE_H
  15. //
  16. // ------------------------------------------------------------------- Includes
  17. //
  18. #include <libcbase.h>
  19. //
  20. // --------------------------------------------------------------------- Macros
  21. //
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. //
  26. // This macros declares a singly-linked list head structure.
  27. //
  28. #define SLIST_HEAD(_HeadName, _Type) \
  29. struct _HeadName { \
  30. struct _Type *slh_first; \
  31. }
  32. //
  33. // This macro evaluates to an initializer for a singly-linked list head.
  34. //
  35. #define SLIST_HEAD_INITIALIZER(_Head) { NULL }
  36. //
  37. // This macro determines whether or not a singly-linked list is empty.
  38. //
  39. #define SLIST_EMPTY(_Head) ((_Head)->slh_first == NULL)
  40. //
  41. // This macros declares a single-linked list element structure.
  42. //
  43. #define SLIST_ENTRY(_Type) \
  44. struct { \
  45. struct _Type *sle_next; \
  46. }
  47. //
  48. // This macro returns the first element of a singly-linked list.
  49. //
  50. #define SLIST_FIRST(_Head) ((_Head)->slh_first)
  51. //
  52. // This macro iterates over the singly-linked list given by _Head, assigning
  53. // each element to _Variable.
  54. //
  55. #define SLIST_FOREACH(_Variable, _Head, _MemberName) \
  56. for ((_Variable) = (_Head)->slh_first; \
  57. (_Variable) != NULL; \
  58. (_Variable) = (_Variable)->_MemberName.sle_next)
  59. //
  60. // This macro initializes the head of a singly-linked list.
  61. //
  62. #define SLIST_INIT(_Head) ((_Head)->slh_first = NULL)
  63. //
  64. // This macro inserts the new element at the singly-linked list head.
  65. //
  66. #define SLIST_INSERT_HEAD(_Head, _New, _MemberName) \
  67. do { \
  68. (_New)->_MemberName.sle_next = (_Head)->slh_first; \
  69. (_Head)->slh_first = (_New); \
  70. \
  71. } while (0)
  72. //
  73. // This macro inserts the new element after the existing singly-linked list
  74. // element.
  75. //
  76. #define SLIST_INSERT_AFTER(_Existing, _New, _MemberName) \
  77. do { \
  78. (_New)->_MemberName.sle_next = (_Existing)->_MemberName.sle_next; \
  79. (_Existing)->_MemberName.sle_next = (_New); \
  80. \
  81. } while (0)
  82. //
  83. // This macro returns the next element in a singly-linked list.
  84. //
  85. #define SLIST_NEXT(_ListEntry, _MemberName) ((_ListEntry)->_MemberName.sle_next)
  86. //
  87. // This macro removes the element at the head of a singly-linked list.
  88. //
  89. #define SLIST_REMOVE_HEAD(_Head, _MemberName) \
  90. (_Head)->slh_first = (_Head)->slh_first->_MemberName.sle_next;
  91. //
  92. // This macro removes an arbitrary element in a singly-linked list.
  93. //
  94. #define SLIST_REMOVE(_Head, _ListEntry, _Type, _MemberName) \
  95. do { \
  96. struct _Type *_CurrentEntry = (_Head)->slh_first; \
  97. if ((_CurrentEntry) == (_ListEntry)) { \
  98. (_Head)->slh_first = (_ListEntry)->_MemberName.sle_next; \
  99. \
  100. } else { \
  101. while ((_CurrentEntry)->_MemberName.sle_next != (_ListEntry)) { \
  102. (_CurrentEntry) = (_CurrentEntry)->_MemberName.sle_next; \
  103. } \
  104. \
  105. (_CurrentEntry)->_MemberName.sle_next = \
  106. (_ListEntry)->_MemberName.sle_next; \
  107. } \
  108. \
  109. } while (0)
  110. //
  111. // This macro declares a singly-linked tail queue head structure. The last
  112. // entry actually stores the address of the last element's next pointer.
  113. //
  114. #define STAILQ_HEAD(_HeadName, _Type) \
  115. struct _HeadName { \
  116. struct _Type *stqh_first; \
  117. struct _Type **stqh_last; \
  118. }
  119. //
  120. // This macro evaluates to an initializer for a singly-linked tail queue head.
  121. //
  122. #define STAILQ_HEAD_INITIALIZER(_Head) { NULL, &((_Head).stqh_first) }
  123. //
  124. // This macro concatenates the tail queue specified by _Head2 onto the end of
  125. // the tail queue specified by _Head1. _Head2 should be empty at the end of the
  126. // macro.
  127. //
  128. #define STAILQ_CONCAT(_Head1, _Head2) \
  129. do { \
  130. if ((_Head2)->stqh_first != NULL) { \
  131. *((_Head1)->stqh_last) = (_Head2)->stqh_first; \
  132. (_Head1)->stqh_last = (_Head2)->stqh_last; \
  133. STAILQ_INIT(_Head2); \
  134. } \
  135. \
  136. } while (0)
  137. //
  138. // This macro determines whether or not a tail queue is empty.
  139. //
  140. #define STAILQ_EMPTY(_Head) ((_Head)->stqh_first == NULL)
  141. //
  142. // This macros declares a tail queue element structure.
  143. //
  144. #define STAILQ_ENTRY(_Type) \
  145. struct { \
  146. struct _Type *stqe_next; \
  147. }
  148. //
  149. // This macro returns the first element of a singly-linked tail queue.
  150. //
  151. #define STAILQ_FIRST(_Head) ((_Head)->stqh_first)
  152. //
  153. // This macro iterates over the singly-linked tail queue given by _Head,
  154. // assigning each element to _Variable.
  155. //
  156. #define STAILQ_FOREACH(_Variable, _Head, _MemberName) \
  157. for ((_Variable) = (_Head)->stqh_first; \
  158. (_Variable) != NULL; \
  159. (_Variable) = (_Variable)->_MemberName.stqe_next)
  160. //
  161. // This macro initializes the head of a singly-linked tail queue.
  162. //
  163. #define STAILQ_INIT(_Head) \
  164. do { \
  165. (_Head)->stqh_first = NULL; \
  166. (_Head)->stqh_last = &((_Head)->stqh_first); \
  167. } while (0)
  168. //
  169. // This macro inserts the _New tail queue element after the _Existing tail
  170. // queue element.
  171. //
  172. #define STAILQ_INSERT_AFTER(_Head, _Existing, _New, _MemberName) \
  173. do { \
  174. (_New)->_MemberName.stqe_next = (_Existing)->_MemberName.stqe_next; \
  175. (_Existing)->_MemberName.stqe_next = (_New); \
  176. if ((_New)->_MemberName.stqe_next == NULL) { \
  177. (_Head)->stqh_last = &((_New)->_MemberName.stqe_next); \
  178. } \
  179. \
  180. } while (0)
  181. //
  182. // This macro inserts the _Entry tail queue element at the head of the
  183. // singly-linked tail queue.
  184. //
  185. #define STAILQ_INSERT_HEAD(_Head, _New, _MemberName) \
  186. do { \
  187. (_New)->_MemberName.stqe_next = (_Head)->stqh_first; \
  188. (_Head)->stqh_first = (_New); \
  189. if ((_New)->_MemberName.stqe_next == NULL) { \
  190. (_Head)->stqh_last = &((_New)->_MemberName.stqe_next); \
  191. } \
  192. \
  193. } while (0)
  194. //
  195. // This macro inserts the _Entry tail queue element at the end of the
  196. // singly-ilnked tail queue.
  197. //
  198. #define STAILQ_INSERT_TAIL(_Head, _New, _MemberName) \
  199. do { \
  200. (_New)->_MemberName.stqe_next = NULL; \
  201. *((_Head)->stqh_last) = (_New); \
  202. (_Head)->stqh_last = &((_New)->_MemberName.stqe_next); \
  203. \
  204. } while (0)
  205. //
  206. // This macro returns the next element in a singly-linked tail queue.
  207. //
  208. #define STAILQ_NEXT(_Entry, _MemberName) ((_Entry)->_MemberName.stqe_next)
  209. //
  210. // This macro removes the element at the head of a singly-linked tail queue.
  211. //
  212. #define STAILQ_REMOVE_HEAD(_Head, _MemberName) \
  213. do { \
  214. (_Head)->stqh_first = (_Head)->stqh_first->_MemberName.stqe_next; \
  215. if ((_Head)->stqh_first == NULL) { \
  216. (_Head)->stqh_last = &((_Head)->stqh_first); \
  217. } \
  218. \
  219. } while (0)
  220. //
  221. // This macro removes the given _Entry tail queue element from the
  222. // singly-linked tail queue.
  223. //
  224. #define STAILQ_REMOVE(_Head, _Entry, _Type, _MemberName) \
  225. do { \
  226. struct _Type *_CurrentEntry = (_Head)->stqh_first; \
  227. if ((_CurrentEntry) == (_Entry)) { \
  228. STAILQ_REMOVE_HEAD(_Head, _MemberName); \
  229. \
  230. } else { \
  231. while ((_CurrentEntry)->_MemberName.stqe_next != (_Entry)) { \
  232. (_CurrentEntry) = (_CurrentEntry)->_MemberName.stqe_next; \
  233. } \
  234. \
  235. (_CurrentEntry)->_MemberName.stqe_next = \
  236. (_Entry)->_MemberName.stqe_next; \
  237. \
  238. if ((_Entry)->_MemberName.stqe_next == NULL) { \
  239. (_Head)->stqh_last = \
  240. &((_CurrentEntry)->_MemberName.stqe_next); \
  241. } \
  242. } \
  243. \
  244. } while (0)
  245. //
  246. // This macro declares a doubly-linked queue head structure.
  247. //
  248. #define LIST_HEAD(_HeadName, _Type) \
  249. struct _HeadName { \
  250. struct _Type *lh_first; \
  251. }
  252. //
  253. // This macro evaluates to an initializer for a doubly-linked list head.
  254. //
  255. #define LIST_HEAD_INITIALIZER(_Head) { NULL }
  256. //
  257. // This macro determines whether or not a doubly linked list is empty.
  258. //
  259. #define LIST_EMPTY(_Head) ((_Head)->lh_first == NULL)
  260. //
  261. // This macro declares a doubly-linked list element structure. In order to
  262. // perform INSERT_BEFORE without being passed the head of the list, the
  263. // previous pointer actually needs to store the address of the previous
  264. // element's next pointer. In the case of the head, this is the address of the
  265. // first entry pointer.
  266. //
  267. #define LIST_ENTRY(_Type) \
  268. struct { \
  269. struct _Type *le_next; \
  270. struct _Type **le_prev; \
  271. }
  272. //
  273. // This macro returns the first element of a doubly-linked list.
  274. //
  275. #define LIST_FIRST(_Head) ((_Head)->lh_first)
  276. //
  277. // This macro iterates over the doubly-linked list given by _Head, assigning
  278. // each element to _Variable.
  279. //
  280. #define LIST_FOREACH(_Variable, _Head, _MemberName) \
  281. for ((_Variable) = (_Head)->lh_first; \
  282. (_Variable) != NULL; \
  283. (_Variable) = (_Variable)->_MemberName.le_next)
  284. //
  285. // This macro initializes the head of a doubly-linked list.
  286. //
  287. #define LIST_INIT(_Head) ((_Head)->lh_first = NULL)
  288. //
  289. // This macro inserts the _New doubly-linked list entry after the _Existing
  290. // entry.
  291. //
  292. #define LIST_INSERT_AFTER(_Existing, _New, _MemberName) \
  293. do { \
  294. (_New)->_MemberName.le_next = (_Existing)->_MemberName.le_next; \
  295. (_New)->_MemberName.le_prev = &((_Existing)->_MemberName.le_next); \
  296. if ((_Existing)->_MemberName.le_next != NULL) { \
  297. (_Existing)->_MemberName.le_next->_MemberName.le_prev = \
  298. &((_New)->_MemberName.le_next); \
  299. } \
  300. \
  301. (_Existing)->_MemberName.le_next = (_New); \
  302. \
  303. } while (0)
  304. //
  305. // This macro inserts the _New doubly-linked list entry before the _Existing
  306. // entry.
  307. //
  308. #define LIST_INSERT_BEFORE(_Existing, _New, _MemberName) \
  309. do { \
  310. (_New)->_MemberName.le_next = (_Existing); \
  311. (_New)->_MemberName.le_prev = (_Existing)->_MemberName.le_prev; \
  312. *((_Existing)->_MemberName.le_prev) = (_New); \
  313. (_Existing)->_MemberName.le_prev = &((_New)->_MemberName.le_next); \
  314. \
  315. } while (0)
  316. //
  317. // This macro inserts the _New doubly-linked list entry at the head of the list.
  318. //
  319. #define LIST_INSERT_HEAD(_Head, _New, _MemberName) \
  320. do { \
  321. (_New)->_MemberName.le_next = (_Head)->lh_first; \
  322. (_New)->_MemberName.le_prev = &((_Head)->lh_first); \
  323. if ((_Head)->lh_first != NULL) { \
  324. (_Head)->lh_first->_MemberName.le_prev = \
  325. &((_New)->_MemberName.le_next); \
  326. } \
  327. \
  328. (_Head)->lh_first = (_New); \
  329. \
  330. } while (0)
  331. //
  332. // This macro gets the next element in the doubly-linked list.
  333. //
  334. #define LIST_NEXT(_Entry, _MemberName) ((_Entry)->_MemberName.le_next)
  335. //
  336. // This macro removes an entry from a doubly-linked list.
  337. //
  338. #define LIST_REMOVE(_Entry, _MemberName) \
  339. do { \
  340. if ((_Entry)->_MemberName.le_next != NULL) { \
  341. (_Entry)->_MemberName.le_next->_MemberName.le_prev = \
  342. (_Entry)->_MemberName.le_prev; \
  343. } \
  344. \
  345. *((_Entry)->_MemberName.le_prev) = (_Entry)->_MemberName.le_next; \
  346. \
  347. } while (0)
  348. //
  349. // This macro swaps the doubly-linked list from _Head1 with the doubly-linked
  350. // list of _Head2.
  351. //
  352. #define LIST_SWAP(_Head1, _Head2, _Type, _MemberName) \
  353. do { \
  354. struct _Type *_SwapEntry = (_Head1)->lh_first; \
  355. (_Head1)->lh_first = (_Head2)->lh_first; \
  356. (_Head2)->lh_first = (_SwapEntry); \
  357. if ((_Head1)->lh_first != NULL) { \
  358. (_Head1)->lh_first->_MemberName.le_prev = &((_Head1)->lh_first); \
  359. } \
  360. \
  361. if ((_Head2)->lh_first != NULL) { \
  362. (_Head2)->lh_first->_MemberName.le_prev = &((_Head2)->lh_first); \
  363. } \
  364. \
  365. } while (0)
  366. //
  367. // This macro defines the structure for a doubly-linked tail queue head. The
  368. // LastEntry is actually a pointer to the last entry's next field. It makes
  369. // this messy and hard to follow, but the macro definitions force this
  370. // implementation.
  371. //
  372. #define TAILQ_HEAD(_HeadName, _Type) \
  373. struct _HeadName { \
  374. struct _Type *tqh_first; \
  375. struct _Type **tqh_last; \
  376. }
  377. //
  378. // This macro evaluates to an initializer for a doubly-linked tail queue.
  379. //
  380. #define TAILQ_HEAD_INITIALIZER(_Head) { NULL, &((_Head).tqh_first) }
  381. //
  382. // This macro concatenates all the entrys from the _Head2 tail queue onto the
  383. // _Head1 tail queue. _Head2 should be empty at the end of the macro.
  384. //
  385. #define TAILQ_CONCAT(_Head1, _Head2, _MemberName) \
  386. do { \
  387. if ((_Head2)->tqh_first != NULL) { \
  388. *((_Head1)->tqh_last) = (_Head2)->tqh_first; \
  389. (_Head2)->tqh_first->_MemberName.tqe_prev = (_Head1)->tqh_last; \
  390. (_Head1)->tqh_last = (_Head2)->tqh_last; \
  391. TAILQ_INIT(_Head2); \
  392. } \
  393. \
  394. } while (0)
  395. //
  396. // This macro determins whether or not a doubly-linked tail queue is empty.
  397. //
  398. #define TAILQ_EMPTY(_Head) ((_Head)->tqh_first == NULL)
  399. //
  400. // This macro defines the structure for a doubly-linked tail queue entry.
  401. //
  402. #define TAILQ_ENTRY(_Type) \
  403. struct { \
  404. struct _Type *tqe_next; \
  405. struct _Type **tqe_prev; \
  406. }
  407. //
  408. // This macro returns the first entry in the doubly-linked tail queue.
  409. //
  410. #define TAILQ_FIRST(_Head) ((_Head)->tqh_first)
  411. //
  412. // This macro iterates over the doubly-linked tail queue given by _Head,
  413. // assigning each element to _Variable.
  414. //
  415. #define TAILQ_FOREACH(_Variable, _Head, _MemberName) \
  416. for ((_Variable) = TAILQ_FIRST(_Head); \
  417. (_Variable) != NULL; \
  418. (_Variable) = TAILQ_NEXT(_Variable, _MemberName))
  419. //
  420. // This macro iterates over the doubly-linked tail queue given by _Head,
  421. // assigning each element to _Variable. It does so in reverse order.
  422. //
  423. #define TAILQ_FOREACH_REVERSE(_Variable, _Head, _HeadName, _MemberName) \
  424. for ((_Variable) = TAILQ_LAST(_Head, _HeadName); \
  425. (_Variable) != NULL; \
  426. (_Variable) = TAILQ_PREV(_Variable, _HeadName, _MemberName)) \
  427. //
  428. // This macro initializes a doubly-linked tail queue head structure.
  429. //
  430. #define TAILQ_INIT(_Head) \
  431. do { \
  432. (_Head)->tqh_first = NULL; \
  433. (_Head)->tqh_last = &((_Head)->tqh_first); \
  434. \
  435. } while (0)
  436. //
  437. // This macro inserts a _New tail queue entry after the _Existing entry.
  438. //
  439. #define TAILQ_INSERT_AFTER(_Head, _Existing, _New, _MemberName) \
  440. do { \
  441. (_New)->_MemberName.tqe_next = (_Existing)->_MemberName.tqe_next; \
  442. (_New)->_MemberName.tqe_prev = &((_Existing)->_MemberName.tqe_next); \
  443. if ((_Existing)->_MemberName.tqe_next != NULL) { \
  444. (_Existing)->_MemberName.tqe_next->_MemberName.tqe_prev = \
  445. &((_New)->_MemberName.tqe_next); \
  446. \
  447. } else { \
  448. (_Head)->tqh_last = &((_New)->_MemberName.tqe_next); \
  449. } \
  450. \
  451. (_Existing)->_MemberName.tqe_next = (_New); \
  452. \
  453. } while (0)
  454. //
  455. // This macro inserts a _New tail queue entry before the _Existing entry.
  456. //
  457. #define TAILQ_INSERT_BEFORE(_Existing, _New, _MemberName) \
  458. do { \
  459. (_New)->_MemberName.tqe_next = (_Existing); \
  460. (_New)->_MemberName.tqe_prev = (_Existing)->_MemberName.tqe_prev; \
  461. *((_Existing)->_MemberName.tqe_prev) = (_New); \
  462. (_Existing)->_MemberName.tqe_prev = &((_New)->_MemberName.tqe_next); \
  463. \
  464. } while (0)
  465. //
  466. // This macro inserts a _New tail queue entry at the head of the tail queue.
  467. //
  468. #define TAILQ_INSERT_HEAD(_Head, _New, _MemberName) \
  469. do { \
  470. (_New)->_MemberName.tqe_next = (_Head)->tqh_first; \
  471. (_New)->_MemberName.tqe_prev = &((_Head)->tqh_first); \
  472. if ((_Head)->tqh_first != NULL) { \
  473. (_Head)->tqh_first->_MemberName.tqe_prev = \
  474. &((_New)->_MemberName.tqe_next); \
  475. \
  476. } else { \
  477. (_Head)->tqh_last = &((_New)->_MemberName.tqe_next); \
  478. } \
  479. \
  480. (_Head)->tqh_first = (_New); \
  481. \
  482. } while (0)
  483. //
  484. // This macro inserts a _New tail queue entry at the end of the tail queue.
  485. //
  486. #define TAILQ_INSERT_TAIL(_Head, _New, _MemberName) \
  487. do { \
  488. (_New)->_MemberName.tqe_next = NULL; \
  489. (_New)->_MemberName.tqe_prev = (_Head)->tqh_last; \
  490. *((_Head)->tqh_last) = (_New); \
  491. (_Head)->tqh_last = &((_New)->_MemberName.tqe_next); \
  492. \
  493. } while (0)
  494. //
  495. // This macro returns the last entry in the doubly-linked tail queue. This is
  496. // gnarly, but forced by the way these macros are defined. What is this doing?
  497. // The head's last entry actually stores the address of the last element's next
  498. // pointer. So it points to the nameless structure that makes up a tail queue
  499. // entry. As it's nameless, its pointers cannot be accessed. Both the _Type and
  500. // _MemberName would be needed to get the base pointer for the _Type structure
  501. // from just this previous next address. What then? Cast it to a _HeadName;
  502. // it's got the same pointer structure! Yikes. The second pointer of the entry
  503. // is actually the address of the previous entry's next field. Dereferencing
  504. // that yields the address of the entry after the previous entry - that is, the
  505. // last entry.
  506. //
  507. #define TAILQ_LAST(_Head, _HeadName) \
  508. (*(((struct _HeadName *)((_Head)->tqh_last))->tqh_last))
  509. //
  510. // This macro returns the next entry in the tail queue.
  511. //
  512. #define TAILQ_NEXT(_Entry, _MemberName) ((_Entry)->_MemberName.tqe_next)
  513. //
  514. // This macro returns the previous entry in the tail queue. See the comments
  515. // about TAILQ_LAST to get a sense of what's going on here.
  516. //
  517. #define TAILQ_PREV(_Entry, _HeadName, _MemberName) \
  518. (*(((struct _HeadName *)((_Entry)->_MemberName.tqe_prev))->tqh_last))
  519. //
  520. // This macro removes the given doubly-linked tail queue entry from the tail
  521. // queue.
  522. //
  523. #define TAILQ_REMOVE(_Head, _Entry, _MemberName) \
  524. do { \
  525. if ((_Entry)->_MemberName.tqe_next == NULL) { \
  526. (_Head)->tqh_last = (_Entry)->_MemberName.tqe_prev; \
  527. \
  528. } else { \
  529. (_Entry)->_MemberName.tqe_next->_MemberName.tqe_prev = \
  530. (_Entry)->_MemberName.tqe_prev; \
  531. } \
  532. \
  533. *((_Entry)->_MemberName.tqe_prev) = (_Entry)->_MemberName.tqe_next; \
  534. \
  535. } while (0)
  536. //
  537. // This macro swaps the tail queue in _Head1 with the tail queue in _Head2;
  538. //
  539. #define TAILQ_SWAP(_Head1, _Head2, _Type, _MemberName) \
  540. do { \
  541. struct _Type *_SwapFirst = (_Head1)->tqh_first; \
  542. struct _Type **_SwapLast = (_Head1)->tqh_last; \
  543. (_Head1)->tqh_first = (_Head2)->tqh_first; \
  544. (_Head1)->tqh_last = (_Head2)->tqh_last; \
  545. (_Head2)->tqh_first = (_SwapFirst); \
  546. (_Head2)->tqh_last = (_SwapLast); \
  547. if ((_Head1)->tqh_first != NULL) { \
  548. (_Head1)->tqh_first->_MemberName.tqe_prev = \
  549. &((_Head1)->tqh_first); \
  550. \
  551. } else { \
  552. (_Head1)->tqh_last = &((_Head1)->tqh_first); \
  553. } \
  554. \
  555. if ((_Head2)->tqh_first != NULL) { \
  556. (_Head2)->tqh_first->_MemberName.tqe_prev = \
  557. &((_Head2)->tqh_first); \
  558. \
  559. } else { \
  560. (_Head2)->tqh_last = &((_Head2)->tqh_first); \
  561. } \
  562. \
  563. } while (0)
  564. //
  565. // ---------------------------------------------------------------- Definitions
  566. //
  567. //
  568. // ------------------------------------------------------ Data Type Definitions
  569. //
  570. //
  571. // -------------------------------------------------------------------- Globals
  572. //
  573. //
  574. // -------------------------------------------------------- Function Prototypes
  575. //
  576. #ifdef __cplusplus
  577. }
  578. #endif
  579. #endif