home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / queue / part01 next >
Text File  |  1993-12-21  |  64KB  |  1,548 lines

  1. Newsgroups: comp.sources.unix
  2. From: bostic@cs.berkeley.edu (Keith Bostic)
  3. Subject: v27i173: queue - implementations of lists, tail queues, and circular queues, Part01/01
  4. Message-id: <1.756504644.8164@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: bostic@cs.berkeley.edu (Keith Bostic)
  9. Posting-Number: Volume 27, Issue 173
  10. Archive-Name: queue/part01
  11.  
  12. Here's the final versions of the queue stuff that we talked
  13. about.  Paul, consider it a submission for unix.sources, if
  14. you like.
  15.  
  16. --keith
  17.  
  18. [ from the manpage...
  19.  
  20.   DESCRIPTION
  21.      These macros define and operate on three types of data structures: lists,
  22.      tail queues, and circular queues.  All three structures support the fol-
  23.      lowing functionality:
  24.            1.   Insertion of a new entry at the head of the list.
  25.            2.   Insertion of a new entry after any element in the list.
  26.            3.   Removal of any entry in the list.
  27.            4.   Forward traversal through the list.
  28.  
  29.   --vix ]
  30.  
  31. # This is a shell archive.  Save it in a file, remove anything before
  32. # this line, and then unpack it by entering "sh file".  Note, it may
  33. # create directories; files and directories will be owned by you and
  34. # have default permissions.
  35. #
  36. # This archive contains:
  37. #
  38. #    queue.0
  39. #    queue.0.ps
  40. #    queue.3
  41. #    queue.h
  42. #
  43. echo x - queue.0
  44. sed 's/^X//' >queue.0 << 'END-of-queue.0'
  45. XQUEUE(3)                    BSD Programmer's Manual                   QUEUE(3)
  46. X
  47. XNNAAMMEE
  48. X     LLIISSTT__EENNTTRRYY, LLIISSTT__HHEEAADD, LLIISSTT__IINNIITT, LLIISSTT__IINNSSEERRTT__AAFFTTEERR, LLIISSTT__IINNSSEERRTT__HHEEAADD,
  49. X     LLIISSTT__RREEMMOOVVEE, TTAAIILLQQ__EENNTTRRYY, TTAAIILLQQ__HHEEAADD, TTAAIILLQQ__IINNIITT, TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR,
  50. X     TTAAIILLQQ__IINNSSEERRTT__HHEEAADD, TTAAIILLQQ__IINNSSEERRTT__TTAAIILL, TTAAIILLQQ__RREEMMOOVVEE, CCIIRRCCLLEEQQ__EENNTTRRYY,
  51. X     CCIIRRCCLLEEQQ__HHEEAADD, CCIIRRCCLLEEQQ__IINNIITT, CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR, CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE,
  52. X     CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD, CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL, CCIIRRCCLLEEQQ__RREEMMOOVVEE - implementa-
  53. X     tions of lists, tail queues, and circular queues
  54. X
  55. XSSYYNNOOPPSSIISS
  56. X     ##iinncclluuddee <<ssyyss//qquueeuuee..hh>>
  57. X
  58. X
  59. X     LLIISSTT__EENNTTRRYY(_T_Y_P_E);
  60. X
  61. X     LLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
  62. X
  63. X     LLIISSTT__IINNIITT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
  64. X
  65. X     LLIISSTT__IINNSSEERRTT__AAFFTTEERR(_L_I_S_T___E_N_T_R_Y _*_l_i_s_t_e_l_m, _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
  66. X
  67. X     LLIISSTT__IINNSSEERRTT__HHEEAADD(_L_I_S_T___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
  68. X
  69. X     LLIISSTT__RREEMMOOVVEE(_T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
  70. X
  71. X
  72. X     TTAAIILLQQ__EENNTTRRYY(_T_Y_P_E);
  73. X
  74. X     TTAAIILLQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
  75. X
  76. X     TTAAIILLQQ__IINNIITT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
  77. X
  78. X     TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_l_i_s_t_e_l_m, _T_Y_P_E _*_e_l_m,
  79. X             _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
  80. X
  81. X     TTAAIILLQQ__IINNSSEERRTT__HHEEAADD(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
  82. X
  83. X     TTAAIILLQQ__IINNSSEERRTT__TTAAIILL(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
  84. X
  85. X     TTAAIILLQQ__RREEMMOOVVEE(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
  86. X
  87. X
  88. X     CCIIRRCCLLEEQQ__EENNTTRRYY(_T_Y_P_E);
  89. X
  90. X     CCIIRRCCLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
  91. X
  92. X     CCIIRRCCLLEEQQ__IINNIITT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
  93. X
  94. X     CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_l_i_s_t_e_l_m, _T_Y_P_E _*_e_l_m,
  95. X             _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
  96. X
  97. X     CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_l_i_s_t_e_l_m, _T_Y_P_E _*_e_l_m,
  98. X             _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
  99. X
  100. X     CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
  101. X
  102. X     CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
  103. X
  104. X     CCIIRRCCLLEEQQ__RREEMMOOVVEE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
  105. X
  106. XDDEESSCCRRIIPPTTIIOONN
  107. X     These macros define and operate on three types of data structures: lists,
  108. X     tail queues, and circular queues.  All three structures support the fol-
  109. X
  110. X     lowing functionality:
  111. X           1.   Insertion of a new entry at the head of the list.
  112. X           2.   Insertion of a new entry after any element in the list.
  113. X           3.   Removal of any entry in the list.
  114. X           4.   Forward traversal through the list.
  115. X
  116. X     Lists are the simplest of the three data structures and support only the
  117. X     above functionality.
  118. X
  119. X     Tail queues add the following functionality:
  120. X           1.   Entries can be added at the end of a list.
  121. X     However:
  122. X           1.   All list insertions and removals must specify the head of the
  123. X                list.
  124. X           2.   Each head entry requires two pointers rather than one.
  125. X           3.   Code size is about 15% greater and operations run about 20%
  126. X                slower than lists.
  127. X
  128. X     Circular queues add the following functionality:
  129. X           1.   Entries can be added at the end of a list.
  130. X           2.   Entries can be added before another entry.
  131. X           3.   They may be traversed backwards, from tail to head.
  132. X     However:
  133. X           1.   All list insertions and removals must specify the head of the
  134. X                list.
  135. X           2.   Each head entry requires two pointers rather than one.
  136. X           3.   The termination condition for traversal is more complex.
  137. X           4.   Code size is about 40% greater and operations run about 45%
  138. X                slower than lists.
  139. X
  140. X     In the macro definitions, _T_Y_P_E is the name of a user defined structure,
  141. X     that must contain a field of type LIST_ENTRY, TAILQ_ENTRY, or
  142. X     CIRCLEQ_ENTRY, named _N_A_M_E. The argument _H_E_A_D_N_A_M_E is the name of a user
  143. X     defined structure that must be declared using the macros LIST_HEAD,
  144. X     TAILQ_HEAD, or CIRCLEQ_HEAD. See the examples below for further explana-
  145. X     tion of how these macros are used.
  146. X
  147. XLLIISSTTSS
  148. X     A list is headed by a structure defined by the LLIISSTT__HHEEAADD macro.  This
  149. X     structure contains a single pointer to the first element on the list.
  150. X     The elements are doubly linked so that an arbitrary element can be re-
  151. X     moved without traversing the list.  New elements can be added to the list
  152. X     after an existing element or at the head of the list.  A _L_I_S_T___H_E_A_D struc-
  153. X     ture is declared as follows:
  154. X
  155. X           LIST_HEAD(HEADNAME, TYPE) head;
  156. X
  157. X     where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and _T_Y_P_E is
  158. X     the type of the elements to be linked into the list.  A pointer to the
  159. X     head of the list can later be declared as:
  160. X
  161. X           struct HEADNAME *headp;
  162. X
  163. X     (The names head and headp are user selectable.)
  164. X
  165. X     The macro LLIISSTT__EENNTTRRYY declares a structure that connects the elements in
  166. X     the list.
  167. X
  168. X     The macro LLIISSTT__IINNIITT initializes the list referenced by _h_e_a_d.
  169. X
  170. X     The macro LLIISSTT__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of the
  171. X     list.
  172. X
  173. X     The macro LLIISSTT__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the element
  174. X     _l_i_s_t_e_l_m.
  175. X
  176. X
  177. X     The macro LLIISSTT__RREEMMOOVVEE removes the element _e_l_m from the list.
  178. X
  179. XLLIISSTT EEXXAAMMPPLLEE
  180. X     LIST_HEAD(listhead, entry) head;
  181. X     struct listhead *headp;         /* List head. */
  182. X     struct entry {
  183. X             ...
  184. X             LIST_ENTRY(entry) entries;      /* List. */
  185. X             ...
  186. X     } *n1, *n2, *np;
  187. X
  188. X     LIST_INIT(&head);                       /* Initialize the list. */
  189. X
  190. X     n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
  191. X     LIST_INSERT_HEAD(&head, n1, entries);
  192. X
  193. X     n2 = malloc(sizeof(struct entry));      /* Insert after. */
  194. X     LIST_INSERT_AFTER(n1, n2, entries);
  195. X                                             /* Forward traversal. */
  196. X     for (np = head.lh_first; np != NULL; np = np->entries.le_next)
  197. X             np-> ...
  198. X
  199. X     while (head.lh_first != NULL)           /* Delete. */
  200. X             LIST_REMOVE(head.lh_first, entries);
  201. X
  202. XTTAAIILL QQUUEEUUEESS
  203. X     A tail queue is headed by a structure defined by the TTAAIILLQQ__HHEEAADD macro.
  204. X     This structure contains a pair of pointers, one to the first element in
  205. X     the tail queue and the other to the last element in the tail queue.  The
  206. X     elements are doubly linked so that an arbitrary element can be removed
  207. X     without traversing the tail queue.  New elements can be added to the tail
  208. X     queue after an existing element, at the head of the tail queue, or at the
  209. X     end of the tail queue.  A _T_A_I_L_Q___H_E_A_D structure is declared as follows:
  210. X
  211. X           TAILQ_HEAD(HEADNAME, TYPE) head;
  212. X
  213. X     where HEADNAME is the name of the structure to be defined, and TYPE is
  214. X     the type of the elements to be linked into the tail queue.  A pointer to
  215. X     the head of the tail queue can later be declared as:
  216. X
  217. X           struct HEADNAME *headp;
  218. X
  219. X     (The names head and headp are user selectable.)
  220. X
  221. X     The macro TTAAIILLQQ__EENNTTRRYY declares a structure that connects the elements in
  222. X     the tail queue.
  223. X
  224. X     The macro TTAAIILLQQ__IINNIITT initializes the tail queue referenced by _h_e_a_d.
  225. X
  226. X     The macro TTAAIILLQQ__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of
  227. X     the tail queue.
  228. X
  229. X     The macro TTAAIILLQQ__IINNSSEERRTT__TTAAIILL inserts the new element _e_l_m at the end of the
  230. X     tail queue.
  231. X
  232. X     The macro TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the ele-
  233. X     ment _l_i_s_t_e_l_m.
  234. X
  235. X     The macro TTAAIILLQQ__RREEMMOOVVEE removes the element _e_l_m from the tail queue.
  236. X
  237. XTTAAIILL QQUUEEUUEE EEXXAAMMPPLLEE
  238. X     TAILQ_HEAD(tailhead, entry) head;
  239. X     struct tailhead *headp;         /* Tail queue head. */
  240. X     struct entry {
  241. X             ...
  242. X             TAILQ_ENTRY(entry) entries;     /* Tail queue. */
  243. X             ...
  244. X     } *n1, *n2, *np;
  245. X
  246. X     TAILQ_INIT(&head);                      /* Initialize the queue. */
  247. X
  248. X     n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
  249. X     TAILQ_INSERT_HEAD(&head, n1, entries);
  250. X
  251. X     n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
  252. X     TAILQ_INSERT_TAIL(&head, n1, entries);
  253. X
  254. X     n2 = malloc(sizeof(struct entry));      /* Insert after. */
  255. X     TAILQ_INSERT_AFTER(&head, n1, n2, entries);
  256. X                                             /* Forward traversal. */
  257. X     for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
  258. X             np-> ...
  259. X                                             /* Delete. */
  260. X     while (head.tqh_first != NULL)
  261. X             TAILQ_REMOVE(&head, head.tqh_first, entries);
  262. X
  263. XCCIIRRCCUULLAARR QQUUEEUUEESS
  264. X     A circular queue is headed by a structure defined by the CCIIRRCCLLEEQQ__HHEEAADD
  265. X     macro.  This structure contains a pair of pointers, one to the first ele-
  266. X     ment in the circular queue and the other to the last element in the cir-
  267. X     cular queue.  The elements are doubly linked so that an arbitrary element
  268. X     can be removed without traversing the queue.  New elements can be added
  269. X     to the queue after an existing element, before an existing element, at
  270. X     the head of the queue, or at the end of the queue.  A _C_I_R_C_L_E_Q___H_E_A_D struc-
  271. X     ture is declared as follows:
  272. X
  273. X           CIRCLEQ_HEAD(HEADNAME, TYPE) head;
  274. X
  275. X     where HEADNAME is the name of the structure to be defined, and TYPE is
  276. X     the type of the elements to be linked into the circular queue.  A pointer
  277. X     to the head of the circular queue can later be declared as:
  278. X
  279. X           struct HEADNAME *headp;
  280. X
  281. X     (The names head and headp are user selectable.)
  282. X
  283. X     The macro CCIIRRCCLLEEQQ__EENNTTRRYY declares a structure that connects the elements
  284. X     in the circular queue.
  285. X
  286. X     The macro CCIIRRCCLLEEQQ__IINNIITT initializes the circular queue referenced by _h_e_a_d.
  287. X
  288. X     The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of
  289. X     the circular queue.
  290. X
  291. X     The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL inserts the new element _e_l_m at the end of
  292. X     the circular queue.
  293. X
  294. X     The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the ele-
  295. X     ment _l_i_s_t_e_l_m.
  296. X
  297. X     The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE inserts the new element _e_l_m before the
  298. X     element _l_i_s_t_e_l_m.
  299. X
  300. X     The macro CCIIRRCCLLEEQQ__RREEMMOOVVEE removes the element _e_l_m from the circular queue.
  301. X
  302. XCCIIRRCCUULLAARR QQUUEEUUEE EEXXAAMMPPLLEE
  303. X     CIRCLEQ_HEAD(circleq, entry) head;
  304. X     struct circleq *headp;                  /* Circular queue head. */
  305. X     struct entry {
  306. X             ...
  307. X             CIRCLEQ_ENTRY entries;          /* Circular queue. */
  308. X             ...
  309. X     } *n1, *n2, *np;
  310. X
  311. X     CIRCLEQ_INIT(&head);                    /* Initialize the circular queue. */
  312. X
  313. X     n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
  314. X     CIRCLEQ_INSERT_HEAD(&head, n1, entries);
  315. X
  316. X     n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
  317. X     CIRCLEQ_INSERT_TAIL(&head, n1, entries);
  318. X
  319. X     n2 = malloc(sizeof(struct entry));      /* Insert after. */
  320. X     CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
  321. X
  322. X     n2 = malloc(sizeof(struct entry));      /* Insert before. */
  323. X     CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
  324. X                                             /* Forward traversal. */
  325. X     for (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
  326. X             np-> ...
  327. X                                             /* Reverse traversal. */
  328. X     for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
  329. X             np-> ...
  330. X                                             /* Delete. */
  331. X     while (head.cqh_first != (void *)&head)
  332. X             CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
  333. X
  334. XHHIISSTTOORRYY
  335. X     The qquueeuuee functions first appeared in 4.4BSD.
  336. X
  337. X4th Berkeley Distribution      December 13, 1993                             5
  338. END-of-queue.0
  339. echo x - queue.0.ps
  340. sed 's/^X//' >queue.0.ps << 'END-of-queue.0.ps'
  341. X%!PS-Adobe-3.0
  342. X%%Creator: groff version 1.08
  343. X%%DocumentNeededResources: font Times-Roman
  344. X%%+ font Times-Bold
  345. X%%+ font Courier-Bold
  346. X%%+ font Courier-Oblique
  347. X%%+ font Symbol
  348. X%%+ font Courier
  349. X%%DocumentSuppliedResources: procset grops 1.08 0
  350. X%%Pages: 5
  351. X%%PageOrder: Ascend
  352. X%%Orientation: Portrait
  353. X%%EndComments
  354. X%%BeginProlog
  355. X%%BeginResource: procset grops 1.08 0
  356. X/setpacking where{
  357. Xpop
  358. Xcurrentpacking
  359. Xtrue setpacking
  360. X}if
  361. X/grops 120 dict dup begin
  362. X/SC 32 def
  363. X/A/show load def
  364. X/B{0 SC 3 -1 roll widthshow}bind def
  365. X/C{0 exch ashow}bind def
  366. X/D{0 exch 0 SC 5 2 roll awidthshow}bind def
  367. X/E{0 rmoveto show}bind def
  368. X/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
  369. X/G{0 rmoveto 0 exch ashow}bind def
  370. X/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
  371. X/I{0 exch rmoveto show}bind def
  372. X/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
  373. X/K{0 exch rmoveto 0 exch ashow}bind def
  374. X/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
  375. X/M{rmoveto show}bind def
  376. X/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
  377. X/O{rmoveto 0 exch ashow}bind def
  378. X/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
  379. X/Q{moveto show}bind def
  380. X/R{moveto 0 SC 3 -1 roll widthshow}bind def
  381. X/S{moveto 0 exch ashow}bind def
  382. X/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
  383. X/SF{
  384. Xfindfont exch
  385. X[exch dup 0 exch 0 exch neg 0 0]makefont
  386. Xdup setfont
  387. X[exch/setfont cvx]cvx bind def
  388. X}bind def
  389. X/MF{
  390. Xfindfont
  391. X[5 2 roll
  392. X0 3 1 roll 
  393. Xneg 0 0]makefont
  394. Xdup setfont
  395. X[exch/setfont cvx]cvx bind def
  396. X}bind def
  397. X/level0 0 def
  398. X/RES 0 def
  399. X/PL 0 def
  400. X/LS 0 def
  401. X/PLG{
  402. Xgsave newpath clippath pathbbox grestore
  403. Xexch pop add exch pop
  404. X}bind def
  405. X/BP{
  406. X/level0 save def
  407. X1 setlinecap
  408. X1 setlinejoin
  409. X72 RES div dup scale
  410. XLS{
  411. X90 rotate
  412. X}{
  413. X0 PL translate
  414. X}ifelse
  415. X1 -1 scale
  416. X}bind def
  417. X/EP{
  418. Xlevel0 restore
  419. Xshowpage
  420. X}bind def
  421. X/DA{
  422. Xnewpath arcn stroke
  423. X}bind def
  424. X/SN{
  425. Xtransform
  426. X.25 sub exch .25 sub exch
  427. Xround .25 add exch round .25 add exch
  428. Xitransform
  429. X}bind def
  430. X/DL{
  431. XSN
  432. Xmoveto
  433. XSN
  434. Xlineto stroke
  435. X}bind def
  436. X/DC{
  437. Xnewpath 0 360 arc closepath
  438. X}bind def
  439. X/TM matrix def
  440. X/DE{
  441. XTM currentmatrix pop
  442. Xtranslate scale newpath 0 0 .5 0 360 arc closepath
  443. XTM setmatrix
  444. X}bind def
  445. X/RC/rcurveto load def
  446. X/RL/rlineto load def
  447. X/ST/stroke load def
  448. X/MT/moveto load def
  449. X/CL/closepath load def
  450. X/FL{
  451. Xcurrentgray exch setgray fill setgray
  452. X}bind def
  453. X/BL/fill load def
  454. X/LW/setlinewidth load def
  455. X/RE{
  456. Xfindfont
  457. Xdup maxlength 1 index/FontName known not{1 add}if dict begin
  458. X{
  459. X1 index/FID ne{def}{pop pop}ifelse
  460. X}forall
  461. X/Encoding exch def
  462. Xdup/FontName exch def
  463. Xcurrentdict end definefont pop
  464. X}bind def
  465. X/DEFS 0 def
  466. X/EBEGIN{
  467. Xmoveto
  468. XDEFS begin
  469. X}bind def
  470. X/EEND/end load def
  471. X/CNT 0 def
  472. X/level1 0 def
  473. X/PBEGIN{
  474. X/level1 save def
  475. Xtranslate
  476. Xdiv 3 1 roll div exch scale
  477. Xneg exch neg exch translate
  478. X0 setgray
  479. X0 setlinecap
  480. X1 setlinewidth
  481. X0 setlinejoin
  482. X10 setmiterlimit
  483. X[]0 setdash
  484. X/setstrokeadjust where{
  485. Xpop
  486. Xfalse setstrokeadjust
  487. X}if
  488. X/setoverprint where{
  489. Xpop
  490. Xfalse setoverprint
  491. X}if
  492. Xnewpath
  493. X/CNT countdictstack def
  494. Xuserdict begin
  495. X/showpage{}def
  496. X}bind def
  497. X/PEND{
  498. Xclear
  499. Xcountdictstack CNT sub{end}repeat
  500. Xlevel1 restore
  501. X}bind def
  502. Xend def
  503. X/setpacking where{
  504. Xpop
  505. Xsetpacking
  506. X}if
  507. X%%EndResource
  508. X%%IncludeResource: font Times-Roman
  509. X%%IncludeResource: font Times-Bold
  510. X%%IncludeResource: font Courier-Bold
  511. X%%IncludeResource: font Courier-Oblique
  512. X%%IncludeResource: font Symbol
  513. X%%IncludeResource: font Courier
  514. Xgrops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
  515. X792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
  516. X/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
  517. X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
  518. X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
  519. X/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
  520. X/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
  521. X/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
  522. X/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash
  523. X/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
  524. X/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
  525. X/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
  526. X/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
  527. X/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
  528. X/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
  529. X/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
  530. X/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
  531. X/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
  532. X/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
  533. X/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
  534. X/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
  535. X/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
  536. X/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
  537. X/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
  538. X/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
  539. X/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE
  540. X/Courier-Oblique@0 ENC0/Courier-Oblique RE/Courier-Bold@0 ENC0/Courier-Bold RE
  541. X/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
  542. X%%EndProlog
  543. X%%Page: 1 1
  544. X%%BeginPageSetup
  545. XBP
  546. X%%EndPageSetup
  547. X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
  548. X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
  549. X/F1 10/Times-Bold@0 SF -.2(NA)72 108 S(ME).2 E/F2 10/Courier-Bold@0 SF
  550. X(LIST_ENTRY)102 120 Q F0(,)A F2(LIST_HEAD)179.375 120 Q F0(,)A F2(LIST_INIT)
  551. X250.75 120 Q F0(,)A F2(LIST_INSERT_AFTER)322.125 120 Q F0(,)A F2
  552. X(LIST_INSERT_HEAD)441.5 120 Q F0(,)A F2(LIST_REMOVE)102 132 Q F0(,)A F2
  553. X(TAILQ_ENTRY)186.875 132 Q F0(,)A F2(TAILQ_HEAD)271.75 132 Q F0(,)A F2
  554. X(TAILQ_INIT)350.625 132 Q F0(,)A F2(TAILQ_INSERT_AFTER)429.5 132 Q F0(,)A F2
  555. X(TAILQ_INSERT_HEAD)102 144 Q F0(,)A F2(TAILQ_INSERT_TAIL)231.167 144 Q F0(,)A
  556. XF2(TAILQ_REMOVE)360.334 144 Q F0(,)A F2(CIRCLEQ_ENTRY)459.5 144 Q F0(,)A F2
  557. X(CIRCLEQ_HEAD)102 156 Q F0(,)A F2(CIRCLEQ_INIT)189.166 156 Q F0(,)A F2
  558. X(CIRCLEQ_INSERT_AFTER)276.333 156 Q F0(,)A F2(CIRCLEQ_INSERT_BEFORE)411.5 156 Q
  559. XF0(,)A F2(CIRCLEQ_INSERT_HEAD)102 168 Q F0(,)A F2(CIRCLEQ_INSERT_TAIL)3.624 E
  560. XF0(,)A F2(CIRCLEQ_REMOVE)3.624 E F0 3.623<ad69>3.623 G 1.123
  561. X(mplementations of lists,)441.914 168 R(tail queues, and circular queues)102
  562. X180 Q F1(SYNOPSIS)72 204 Q F2(#include <sys/queue.h>)102 216 Q(LIST_ENTRY)102
  563. X246 Q F0(\()A/F3 10/Courier-Oblique@0 SF(TYPE)A F0(\);)A F2(LIST_HEAD)102 264 Q
  564. XF0(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)4.166 E F0(\);)A F2(LIST_INIT)102
  565. X282 Q F0(\()A F3(LIST_HEAD)A/F4 10/Symbol SF(*)6 E F3(head)A F0(\);)A F2
  566. X(LIST_INSERT_AFTER)102 300 Q F0(\()A F3(LIST_ENTRY)A F4(*)6 E F3(listelm)A F0
  567. X(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(LIST_ENTRY NAME)
  568. X4.166 E F0(\);)A F2(LIST_INSERT_HEAD)102 318 Q F0(\()A F3(LIST_HEAD)A F4(*)6 E
  569. XF3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
  570. X(LIST_ENTRY NAME)4.166 E F0(\);)A F2(LIST_REMOVE)102 336 Q F0(\()A F3(TYPE)A F4
  571. X(*)6 E F3(elm)A F0(,)1.666 E F3(LIST_ENTRY NAME)4.166 E F0(\);)A F2
  572. X(TAILQ_ENTRY)102 366 Q F0(\()A F3(TYPE)A F0(\);)A F2(TAILQ_HEAD)102 384 Q F0
  573. X(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)4.166 E F0(\);)A F2(TAILQ_INIT)102 402
  574. XQ F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(\);)A F2(TAILQ_INSERT_AFTER)102
  575. X420 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E
  576. XF4(*)6 E F3(listelm)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666
  577. XE F3(TAILQ_ENTRY NAME)151.666 432 Q F0(\);)A F2(TAILQ_INSERT_HEAD)102 450 Q F0
  578. X(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E
  579. XF3(elm)A F0(,)1.666 E F3(TAILQ_ENTRY NAME)4.166 E F0(\);)A F2
  580. X(TAILQ_INSERT_TAIL)102 468 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)
  581. X1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(TAILQ_ENTRY NAME)
  582. X4.166 E F0(\);)A F2(TAILQ_REMOVE)102 486 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3
  583. X(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
  584. X(TAILQ_ENTRY NAME)4.166 E F0(\);)A F2(CIRCLEQ_ENTRY)102 516 Q F0(\()A F3(TYPE)A
  585. XF0(\);)A F2(CIRCLEQ_HEAD)102 534 Q F0(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)
  586. X4.166 E F0(\);)A F2(CIRCLEQ_INIT)102 552 Q F0(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E
  587. XF3(head)A F0(\);)A F2(CIRCLEQ_INSERT_AFTER)102 570 Q F0(\()A F3(CIRCLEQ_HEAD)A
  588. XF4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(listelm)A F0(,)
  589. X1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)
  590. X151.666 582 Q F0(\);)A F2(CIRCLEQ_INSERT_BEFORE)102 600 Q F0(\()A F3
  591. X(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3
  592. X(listelm)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
  593. X(CIRCLEQ_ENTRY NAME)151.666 612 Q F0(\);)A F2(CIRCLEQ_INSERT_HEAD)102 630 Q F0
  594. X(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6
  595. XE F3(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A F2
  596. X(CIRCLEQ_INSERT_TAIL)102 648 Q F0(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0
  597. X(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
  598. X(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A F2(CIRCLEQ_REMOVE)102 666 Q F0(\()A F3
  599. X(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3
  600. X(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A(4th Berk)72 750 Q
  601. X(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F
  602. X(13, 1993)2.5 E(1)535 750 Q EP
  603. X%%Page: 2 2
  604. X%%BeginPageSetup
  605. XBP
  606. X%%EndPageSetup
  607. X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
  608. X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
  609. X/F1 10/Times-Bold@0 SF(DESCRIPTION)72 96 Q F0 .264(These macros de\214ne and o\
  610. Xperate on three types of data structures: lists, tail queues, and circular que\
  611. Xues.)102 108 R(All)5.263 E(three structures support the follo)102 120 Q
  612. X(wing functionality:)-.25 E 10(1. Insertion)132 132 R(of a ne)2.5 E 2.5(we)-.25
  613. XG(ntry at the head of the list.)231.17 132 Q 10(2. Insertion)132 144 R(of a ne)
  614. X2.5 E 2.5(we)-.25 G(ntry after an)231.17 144 Q 2.5(ye)-.15 G
  615. X(lement in the list.)291.83 144 Q 10(3. Remo)132 156 R -.25(va)-.15 G 2.5(lo)
  616. X.25 G 2.5(fa)195.21 156 S .3 -.15(ny e)205.48 156 T(ntry in the list.).15 E 10
  617. X(4. F)132 168 R(orw)-.15 E(ard tra)-.1 E -.15(ve)-.2 G(rsal through the list.)
  618. X.15 E
  619. X(Lists are the simplest of the three data structures and support only the abo)
  620. X102 186 Q .3 -.15(ve f)-.15 H(unctionality).15 E(.)-.65 E -.8(Ta)102 204 S
  621. X(il queues add the follo).8 E(wing functionality:)-.25 E 10(1. Entries)132 216
  622. XR(can be added at the end of a list.)2.5 E(Ho)102 228 Q(we)-.25 E -.15(ve)-.25
  623. XG(r:).15 E 10(1. All)132 240 R(list insertions and remo)2.5 E -.25(va)-.15 G
  624. X(ls must specify the head of the list.).25 E 10(2. Each)132 252 R
  625. X(head entry requires tw)2.5 E 2.5(op)-.1 G(ointers rather than one.)276.03 252
  626. XQ 10(3. Code)132 264 R
  627. X(size is about 15% greater and operations run about 20% slo)2.5 E
  628. X(wer than lists.)-.25 E(Circular queues add the follo)102 282 Q
  629. X(wing functionality:)-.25 E 10(1. Entries)132 294 R
  630. X(can be added at the end of a list.)2.5 E 10(2. Entries)132 306 R
  631. X(can be added before another entry)2.5 E(.)-.65 E 10(3. The)132 318 R 2.5(ym)
  632. X-.15 G(ay be tra)182.68 318 Q -.15(ve)-.2 G(rsed backw).15 E
  633. X(ards, from tail to head.)-.1 E(Ho)102 330 Q(we)-.25 E -.15(ve)-.25 G(r:).15 E
  634. X10(1. All)132 342 R(list insertions and remo)2.5 E -.25(va)-.15 G
  635. X(ls must specify the head of the list.).25 E 10(2. Each)132 354 R
  636. X(head entry requires tw)2.5 E 2.5(op)-.1 G(ointers rather than one.)276.03 354
  637. XQ 10(3. The)132 366 R(termination condition for tra)2.5 E -.15(ve)-.2 G
  638. X(rsal is more comple).15 E(x.)-.15 E 10(4. Code)132 378 R
  639. X(size is about 40% greater and operations run about 45% slo)2.5 E
  640. X(wer than lists.)-.25 E 1.455(In the macro de\214nitions,)102 396 R/F2 10
  641. X/Courier-Oblique@0 SF(TYPE)3.955 E F0 1.456(is the name of a user de\214ned st\
  642. Xructure, that must contain a \214eld of type)3.956 F/F3 10/Courier@0 SF
  643. X(LIST_ENTRY)102 408 Q F0(,)A F3(TAILQ_ENTRY)4.498 E F0 4.498(,o)C(r)246.996 408
  644. XQ F3(CIRCLEQ_ENTRY)4.498 E F0 4.498(,n)C(amed)344.822 408 Q F2(NAME)4.498 E F0
  645. X4.498(.T)C 1.998(he ar)408.088 408 R(gument)-.18 E F2(HEADNAME)4.498 E F0 1.998
  646. X(is the)4.498 F 1.141
  647. X(name of a user de\214ned structure that must be declared using the macros)102
  648. X420 R F3(LIST_HEAD)3.642 E F0(,)A F3(TAILQ_HEAD)3.642 E F0 3.642(,o)C(r)536.67
  649. X420 Q F3(CIRCLEQ_HEAD)102 432 Q F0 2.5(.S)C(ee the e)184.56 432 Q(xamples belo)
  650. X-.15 E 2.5(wf)-.25 G(or further e)280.8 432 Q(xplanation of ho)-.15 E 2.5(wt)
  651. X-.25 G(hese macros are used.)403.43 432 Q F1(LISTS)72 456 Q F0 2.664(Al)102 468
  652. XS .164(ist is headed by a structure de\214ned by the)114.664 468 R/F4 10
  653. X/Courier-Bold@0 SF(LIST_HEAD)2.663 E F0 2.663(macro. This)2.663 F .163
  654. X(structure contains a single pointer to)2.663 F 1.149
  655. X(the \214rst element on the list.)102 480 R 1.149(The elements are doubly link)
  656. X6.149 F 1.15(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G
  657. X(d).15 E .441(without tra)102 492 R -.15(ve)-.2 G .441(rsing the list.).15 F
  658. X(Ne)5.441 E 2.941(we)-.25 G .441(lements can be added to the list after an e)
  659. X239.425 492 R .441(xisting element or at the head of)-.15 F(the list.)102 504 Q
  660. X(A)5 E F2(LIST_HEAD)2.5 E F0(structure is declared as follo)2.5 E(ws:)-.25 E F3
  661. X(LIST_HEAD\(HEADNAME, TYPE\) head;)132 522 Q F0(where)102 546 Q F2(HEADNAME)
  662. X3.622 E F0 1.122(is the name of the structure to be de\214ned, and)3.622 F F2
  663. X(TYPE)3.623 E F0 1.123(is the type of the elements to be)3.623 F(link)102 558 Q
  664. X(ed into the list.)-.1 E 2.5(Ap)5 G
  665. X(ointer to the head of the list can later be declared as:)196.63 558 Q F3
  666. X(struct HEADNAME)132 576 Q/F5 10/Symbol SF(*)6 E F3(headp;)A F0(\(The names)102
  667. X600 Q F3(head)2.5 E F0(and)2.5 E F3(headp)2.5 E F0(are user selectable.\))2.5 E
  668. X(The macro)102 618 Q F4(LIST_ENTRY)2.5 E F0
  669. X(declares a structure that connects the elements in the list.)2.5 E(The macro)
  670. X102 636 Q F4(LIST_INIT)2.5 E F0(initializes the list referenced by)2.5 E F2
  671. X(head)2.5 E F0(.)A(The macro)102 654 Q F4(LIST_INSERT_HEAD)2.5 E F0
  672. X(inserts the ne)2.5 E 2.5(we)-.25 G(lement)312.72 654 Q F2(elm)2.5 E F0
  673. X(at the head of the list.)2.5 E(The macro)102 672 Q F4(LIST_INSERT_AFTER)2.5 E
  674. XF0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)318.72 672 Q F2(elm)2.5 E F0
  675. X(after the element)2.5 E F2(listelm)2.5 E F0(.)A(The macro)102 690 Q F4
  676. X(LIST_REMOVE)2.5 E F0(remo)2.5 E -.15(ve)-.15 G 2.5(st).15 G(he element)254.9
  677. X690 Q F2(elm)2.5 E F0(from the list.)2.5 E(4th Berk)72 750 Q(ele)-.1 E 2.5(yD)
  678. X-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(2)535 750
  679. XQ EP
  680. X%%Page: 3 3
  681. X%%BeginPageSetup
  682. XBP
  683. X%%EndPageSetup
  684. X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
  685. X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
  686. X/F1 10/Times-Bold@0 SF 1.666(LIST EXAMPLE)72 96 R/F2 10/Courier@0 SF
  687. X(LIST_HEAD\(listhead, entry\) head;)102 126 Q(struct listhead)102 138 Q/F3 10
  688. X/Symbol SF(*)6 E F2 82(headp; /)B F3(*)A F2(List head.)6 E F3(*)6 E F2(/)A
  689. X(struct entry {)102 150 Q(...)147 162 Q(LIST_ENTRY\(entry\) entries;)147 174 Q
  690. X(/)327 174 Q F3(*)A F2(List.)6 E F3(*)6 E F2(/)A(...)147 186 Q(})102 198 Q F3
  691. X(*)6 E F2(n1,)A F3(*)6 E F2(n2,)A F3(*)6 E F2(np;)A 117(LIST_INIT\(&head\); /)
  692. X102 222 R F3(*)A F2(Initialize the list.)6 E F3(*)6 E F2(/)A
  693. X(n1 = malloc\(sizeof\(struct entry\)\);)102 246 Q(/)327 246 Q F3(*)A F2
  694. X(Insert at the head.)6 E F3(*)6 E F2(/)A
  695. X(LIST_INSERT_HEAD\(&head, n1, entries\);)102 258 Q
  696. X(n2 = malloc\(sizeof\(struct entry\)\);)102 282 Q(/)327 282 Q F3(*)A F2
  697. X(Insert after.)6 E F3(*)6 E F2(/)A(LIST_INSERT_AFTER\(n1, n2, entries\);)102
  698. X294 Q(/)327 306 Q F3(*)A F2(Forward traversal.)6 E F3(*)6 E F2(/)A
  699. X(for \(np = head.lh_first; np != NULL; np = np->entries.le_next\))102 318 Q
  700. X(np-> ...)147 330 Q(while \(head.lh_first != NULL\))102 354 Q(/)327 354 Q F3(*)
  701. XA F2(Delete.)6 E F3(*)6 E F2(/)A(LIST_REMOVE\(head.lh_first, entries\);)147 366
  702. XQ F1 -.9(TA)72 390 S 1.666(IL Q).9 F(UEUES)-.1 E F0 2.98(At)102 402 S .48
  703. X(ail queue is headed by a structure de\214ned by the)114.98 402 R/F4 10
  704. X/Courier-Bold@0 SF(TAILQ_HEAD)2.979 E F0 2.979(macro. This)2.979 F .479
  705. X(structure contains a pair of)2.979 F .227(pointers, one to the \214rst elemen\
  706. Xt in the tail queue and the other to the last element in the tail queue.)102
  707. X414 R .228(The ele-)5.228 F .387(ments are doubly link)102 426 R .387
  708. X(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G 2.887(dw).15
  709. XG .387(ithout tra)390.075 426 R -.15(ve)-.2 G .387(rsing the tail queue.).15 F
  710. X(Ne)5.387 E(w)-.25 E .45(elements can be added to the tail queue after an e)102
  711. X438 R .451(xisting element, at the head of the tail queue, or at the end)-.15 F
  712. X(of the tail queue.)102 450 Q(A)5 E/F5 10/Courier-Oblique@0 SF(TAILQ_HEAD)2.5 E
  713. XF0(structure is declared as follo)2.5 E(ws:)-.25 E F2
  714. X(TAILQ_HEAD\(HEADNAME, TYPE\) head;)132 468 Q F0(where)102 492 Q F2(HEADNAME)
  715. X3.623 E F0 1.123(is the name of the structure to be de\214ned, and)3.623 F F2
  716. X(TYPE)3.622 E F0 1.122(is the type of the elements to be)3.622 F(link)102 504 Q
  717. X(ed into the tail queue.)-.1 E 2.5(Ap)5 G
  718. X(ointer to the head of the tail queue can later be declared as:)223.56 504 Q F2
  719. X(struct HEADNAME)132 522 Q F3(*)6 E F2(headp;)A F0(\(The names)102 546 Q F2
  720. X(head)2.5 E F0(and)2.5 E F2(headp)2.5 E F0(are user selectable.\))2.5 E
  721. X(The macro)102 564 Q F4(TAILQ_ENTRY)2.5 E F0
  722. X(declares a structure that connects the elements in the tail queue.)2.5 E
  723. X(The macro)102 582 Q F4(TAILQ_INIT)2.5 E F0
  724. X(initializes the tail queue referenced by)2.5 E F5(head)2.5 E F0(.)A(The macro)
  725. X102 600 Q F4(TAILQ_INSERT_HEAD)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G
  726. X(lement)318.72 600 Q F5(elm)2.5 E F0(at the head of the tail queue.)2.5 E
  727. X(The macro)102 618 Q F4(TAILQ_INSERT_TAIL)2.5 E F0(inserts the ne)2.5 E 2.5(we)
  728. X-.25 G(lement)318.72 618 Q F5(elm)2.5 E F0(at the end of the tail queue.)2.5 E
  729. X(The macro)102 636 Q F4(TAILQ_INSERT_AFTER)2.5 E F0(inserts the ne)2.5 E 2.5
  730. X(we)-.25 G(lement)324.72 636 Q F5(elm)2.5 E F0(after the element)2.5 E F5
  731. X(listelm)2.5 E F0(.)A(The macro)102 654 Q F4(TAILQ_REMOVE)2.5 E F0(remo)2.5 E
  732. X-.15(ve)-.15 G 2.5(st).15 G(he element)260.9 654 Q F5(elm)2.5 E F0
  733. X(from the tail queue.)2.5 E F1 -.9(TA)72 678 S 1.666(IL Q).9 F 1.666
  734. X(UEUE EXAMPLE)-.1 F F0(4th Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85
  735. X750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(3)535 750 Q EP
  736. X%%Page: 4 4
  737. X%%BeginPageSetup
  738. XBP
  739. X%%EndPageSetup
  740. X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
  741. X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
  742. X/F1 10/Courier@0 SF(TAILQ_HEAD\(tailhead, entry\) head;)102 96 Q
  743. X(struct tailhead)102 108 Q/F2 10/Symbol SF(*)6 E F1 82(headp; /)B F2(*)A F1
  744. X(Tail queue head.)6 E F2(*)6 E F1(/)A(struct entry {)102 120 Q(...)147 132 Q
  745. X(TAILQ_ENTRY\(entry\) entries;)147 144 Q(/)327 144 Q F2(*)A F1(Tail queue.)6 E
  746. XF2(*)6 E F1(/)A(...)147 156 Q(})102 168 Q F2(*)6 E F1(n1,)A F2(*)6 E F1(n2,)A
  747. XF2(*)6 E F1(np;)A 111(TAILQ_INIT\(&head\); /)102 192 R F2(*)A F1
  748. X(Initialize the queue.)6 E F2(*)6 E F1(/)A
  749. X(n1 = malloc\(sizeof\(struct entry\)\);)102 216 Q(/)327 216 Q F2(*)A F1
  750. X(Insert at the head.)6 E F2(*)6 E F1(/)A
  751. X(TAILQ_INSERT_HEAD\(&head, n1, entries\);)102 228 Q
  752. X(n1 = malloc\(sizeof\(struct entry\)\);)102 252 Q(/)327 252 Q F2(*)A F1
  753. X(Insert at the tail.)6 E F2(*)6 E F1(/)A
  754. X(TAILQ_INSERT_TAIL\(&head, n1, entries\);)102 264 Q
  755. X(n2 = malloc\(sizeof\(struct entry\)\);)102 288 Q(/)327 288 Q F2(*)A F1
  756. X(Insert after.)6 E F2(*)6 E F1(/)A
  757. X(TAILQ_INSERT_AFTER\(&head, n1, n2, entries\);)102 300 Q(/)327 312 Q F2(*)A F1
  758. X(Forward traversal.)6 E F2(*)6 E F1(/)A
  759. X(for \(np = head.tqh_first; np != NULL; np = np->entries.tqe_next\))102 324 Q
  760. X(np-> ...)147 336 Q(/)327 348 Q F2(*)A F1(Delete.)6 E F2(*)6 E F1(/)A
  761. X(while \(head.tqh_first != NULL\))102 360 Q
  762. X(TAILQ_REMOVE\(&head, head.tqh_first, entries\);)147 372 Q/F3 10/Times-Bold@0
  763. XSF 1.666(CIRCULAR Q)72 396 R(UEUES)-.1 E F0 2.984(Ac)102 408 S .484
  764. X(ircular queue is headed by a structure de\214ned by the)116.644 408 R/F4 10
  765. X/Courier-Bold@0 SF(CIRCLEQ_HEAD)2.985 E F0 2.985(macro. This)2.985 F .485
  766. X(structure contains a)2.985 F .358(pair of pointers, one to the \214rst elemen\
  767. Xt in the circular queue and the other to the last element in the circular)102
  768. X420 R 3.33(queue. The)102 432 R .83(elements are doubly link)3.33 F .83
  769. X(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G 3.33(dw).15 G
  770. X.83(ithout tra)458.14 432 R -.15(ve)-.2 G .83(rsing the).15 F 2.796(queue. Ne)
  771. X102 444 R 2.796(we)-.25 G .296(lements can be added to the queue after an e)
  772. X159.542 444 R .295(xisting element, before an e)-.15 F .295
  773. X(xisting element, at the)-.15 F(head of the queue, or at the end of the queue.)
  774. X102 456 Q(A)5 E/F5 10/Courier-Oblique@0 SF(CIRCLEQ_HEAD)2.5 E F0
  775. X(structure is declared as follo)2.5 E(ws:)-.25 E F1
  776. X(CIRCLEQ_HEAD\(HEADNAME, TYPE\) head;)132 474 Q F0(where)102 498 Q F1(HEADNAME)
  777. X3.622 E F0 1.122(is the name of the structure to be de\214ned, and)3.622 F F1
  778. X(TYPE)3.623 E F0 1.123(is the type of the elements to be)3.623 F(link)102 510 Q
  779. X(ed into the circular queue.)-.1 E 2.5(Ap)5 G
  780. X(ointer to the head of the circular queue can later be declared as:)241.32 510
  781. XQ F1(struct HEADNAME)132 528 Q F2(*)6 E F1(headp;)A F0(\(The names)102 552 Q F1
  782. X(head)2.5 E F0(and)2.5 E F1(headp)2.5 E F0(are user selectable.\))2.5 E
  783. X(The macro)102 570 Q F4(CIRCLEQ_ENTRY)2.5 E F0
  784. X(declares a structure that connects the elements in the circular queue.)2.5 E
  785. X(The macro)102 588 Q F4(CIRCLEQ_INIT)2.5 E F0
  786. X(initializes the circular queue referenced by)2.5 E F5(head)2.5 E F0(.)A
  787. X(The macro)102 606 Q F4(CIRCLEQ_INSERT_HEAD)2.5 E F0(inserts the ne)2.5 E 2.5
  788. X(we)-.25 G(lement)330.72 606 Q F5(elm)2.5 E F0
  789. X(at the head of the circular queue.)2.5 E(The macro)102 624 Q F4
  790. X(CIRCLEQ_INSERT_TAIL)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)330.72
  791. X624 Q F5(elm)2.5 E F0(at the end of the circular queue.)2.5 E(The macro)102 642
  792. XQ F4(CIRCLEQ_INSERT_AFTER)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)
  793. X336.72 642 Q F5(elm)2.5 E F0(after the element)2.5 E F5(listelm)2.5 E F0(.)A
  794. X(The macro)102 660 Q F4(CIRCLEQ_INSERT_BEFORE)2.5 E F0(inserts the ne)2.5 E 2.5
  795. X(we)-.25 G(lement)342.72 660 Q F5(elm)2.5 E F0(before the element)2.5 E F5
  796. X(listelm)2.5 E F0(.)A(The macro)102 678 Q F4(CIRCLEQ_REMOVE)2.5 E F0(remo)2.5 E
  797. X-.15(ve)-.15 G 2.5(st).15 G(he element)272.9 678 Q F5(elm)2.5 E F0
  798. X(from the circular queue.)2.5 E(4th Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G
  799. X(istrib)132.85 750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(4)535 750 Q EP
  800. X%%Page: 5 5
  801. X%%BeginPageSetup
  802. XBP
  803. X%%EndPageSetup
  804. X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
  805. X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
  806. X/F1 10/Times-Bold@0 SF 1.666(CIRCULAR Q)72 96 R 1.666(UEUE EXAMPLE)-.1 F/F2 10
  807. X/Courier@0 SF(CIRCLEQ_HEAD\(circleq, entry\) head;)102 126 Q(struct circleq)102
  808. X138 Q/F3 10/Symbol SF(*)6 E F2 88(headp; /)B F3(*)A F2(Circular queue head.)6 E
  809. XF3(*)6 E F2(/)A(struct entry {)102 150 Q(...)147 162 Q(CIRCLEQ_ENTRY entries;)
  810. X147 174 Q(/)327 174 Q F3(*)A F2(Circular queue.)6 E F3(*)6 E F2(/)A(...)147 186
  811. XQ(})102 198 Q F3(*)6 E F2(n1,)A F3(*)6 E F2(n2,)A F3(*)6 E F2(np;)A 99
  812. X(CIRCLEQ_INIT\(&head\); /)102 222 R F3(*)A F2(Initialize the circular queue.)6
  813. XE F3(*)6 E F2(/)A(n1 = malloc\(sizeof\(struct entry\)\);)102 246 Q(/)327 246 Q
  814. XF3(*)A F2(Insert at the head.)6 E F3(*)6 E F2(/)A
  815. X(CIRCLEQ_INSERT_HEAD\(&head, n1, entries\);)102 258 Q
  816. X(n1 = malloc\(sizeof\(struct entry\)\);)102 282 Q(/)327 282 Q F3(*)A F2
  817. X(Insert at the tail.)6 E F3(*)6 E F2(/)A
  818. X(CIRCLEQ_INSERT_TAIL\(&head, n1, entries\);)102 294 Q
  819. X(n2 = malloc\(sizeof\(struct entry\)\);)102 318 Q(/)327 318 Q F3(*)A F2
  820. X(Insert after.)6 E F3(*)6 E F2(/)A
  821. X(CIRCLEQ_INSERT_AFTER\(&head, n1, n2, entries\);)102 330 Q
  822. X(n2 = malloc\(sizeof\(struct entry\)\);)102 354 Q(/)327 354 Q F3(*)A F2
  823. X(Insert before.)6 E F3(*)6 E F2(/)A
  824. X(CIRCLEQ_INSERT_BEFORE\(&head, n1, n2, entries\);)102 366 Q(/)327 378 Q F3(*)A
  825. XF2(Forward traversal.)6 E F3(*)6 E F2(/)A
  826. X(for \(np = head.cqh_first; np != \(void)102 390 Q F3(*)6 E F2
  827. X(\)&head; np = np->entries.cqe_next\))A(np-> ...)147 402 Q(/)327 414 Q F3(*)A
  828. XF2(Reverse traversal.)6 E F3(*)6 E F2(/)A
  829. X(for \(np = head.cqh_last; np != \(void)102 426 Q F3(*)6 E F2
  830. X(\)&head; np = np->entries.cqe_prev\))A(np-> ...)147 438 Q(/)327 450 Q F3(*)A
  831. XF2(Delete.)6 E F3(*)6 E F2(/)A(while \(head.cqh_first != \(void)102 462 Q F3(*)
  832. X6 E F2(\)&head\))A(CIRCLEQ_REMOVE\(&head, head.cqh_first, entries\);)147 474 Q
  833. XF1(HIST)72 498 Q(OR)-.18 E(Y)-.35 E F0(The)102 510 Q/F4 10/Courier-Bold@0 SF
  834. X(queue)2.5 E F0(functions \214rst appeared in 4.4BSD.)2.5 E(4th Berk)72 750 Q
  835. X(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F
  836. X(13, 1993)2.5 E(5)535 750 Q EP
  837. X%%Trailer
  838. Xend
  839. X%%EOF
  840. END-of-queue.0.ps
  841. echo x - queue.3
  842. sed 's/^X//' >queue.3 << 'END-of-queue.3'
  843. X.\" Copyright (c) 1993 The Regents of the University of California.
  844. X.\" All rights reserved.
  845. X.\"
  846. X.\" Redistribution and use in source and binary forms, with or without
  847. X.\" modification, are permitted provided that the following conditions
  848. X.\" are met:
  849. X.\" 1. Redistributions of source code must retain the above copyright
  850. X.\"    notice, this list of conditions and the following disclaimer.
  851. X.\" 2. Redistributions in binary form must reproduce the above copyright
  852. X.\"    notice, this list of conditions and the following disclaimer in the
  853. X.\"    documentation and/or other materials provided with the distribution.
  854. X.\" 3. All advertising materials mentioning features or use of this software
  855. X.\"    must display the following acknowledgement:
  856. X.\"    This product includes software developed by the University of
  857. X.\"    California, Berkeley and its contributors.
  858. X.\" 4. Neither the name of the University nor the names of its contributors
  859. X.\"    may be used to endorse or promote products derived from this software
  860. X.\"    without specific prior written permission.
  861. X.\"
  862. X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  863. X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  864. X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  865. X.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  866. X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  867. X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  868. X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  869. X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  870. X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  871. X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  872. X.\" SUCH DAMAGE.
  873. X.\"
  874. X.\"    @(#)queue.3    8.1 (Berkeley) 12/13/93
  875. X.\"
  876. X.Dd "December 13, 1993"
  877. X.Dt QUEUE 3
  878. X.Os BSD 4
  879. X.Sh NAME
  880. X.Nm LIST_ENTRY ,
  881. X.Nm LIST_HEAD ,
  882. X.Nm LIST_INIT ,
  883. X.Nm LIST_INSERT_AFTER ,
  884. X.Nm LIST_INSERT_HEAD ,
  885. X.Nm LIST_REMOVE ,
  886. X.Nm TAILQ_ENTRY ,
  887. X.Nm TAILQ_HEAD ,
  888. X.Nm TAILQ_INIT ,
  889. X.Nm TAILQ_INSERT_AFTER ,
  890. X.Nm TAILQ_INSERT_HEAD ,
  891. X.Nm TAILQ_INSERT_TAIL ,
  892. X.Nm TAILQ_REMOVE ,
  893. X.Nm CIRCLEQ_ENTRY ,
  894. X.Nm CIRCLEQ_HEAD ,
  895. X.Nm CIRCLEQ_INIT ,
  896. X.Nm CIRCLEQ_INSERT_AFTER ,
  897. X.Nm CIRCLEQ_INSERT_BEFORE ,
  898. X.Nm CIRCLEQ_INSERT_HEAD ,
  899. X.Nm CIRCLEQ_INSERT_TAIL ,
  900. X.Nm CIRCLEQ_REMOVE
  901. X.Nd implementations of lists, tail queues, and circular queues
  902. X.Sh SYNOPSIS
  903. X.Fd #include <sys/queue.h>
  904. X.sp
  905. X.Fn LIST_ENTRY "TYPE"
  906. X.Fn LIST_HEAD "HEADNAME" "TYPE"
  907. X.Fn LIST_INIT "LIST_HEAD *head"
  908. X.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
  909. X.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
  910. X.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
  911. X.sp
  912. X.Fn TAILQ_ENTRY "TYPE"
  913. X.Fn TAILQ_HEAD "HEADNAME" "TYPE"
  914. X.Fn TAILQ_INIT "TAILQ_HEAD *head"
  915. X.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
  916. X.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
  917. X.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
  918. X.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
  919. X.sp
  920. X.Fn CIRCLEQ_ENTRY "TYPE"
  921. X.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
  922. X.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
  923. X.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
  924. X.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
  925. X.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
  926. X.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
  927. X.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
  928. X.Sh DESCRIPTION
  929. XThese macros define and operate on three types of data structures:
  930. Xlists, tail queues, and circular queues.
  931. XAll three structures support the following functionality:
  932. X.Bl -enum -compact -offset indent
  933. X.It
  934. XInsertion of a new entry at the head of the list.
  935. X.It
  936. XInsertion of a new entry after any element in the list.
  937. X.It
  938. XRemoval of any entry in the list.
  939. X.It
  940. XForward traversal through the list.
  941. X.El
  942. X.Pp
  943. XLists are the simplest of the three data structures and support
  944. Xonly the above functionality.
  945. X.Pp
  946. XTail queues add the following functionality:
  947. X.Bl -enum -compact -offset indent
  948. X.It
  949. XEntries can be added at the end of a list.
  950. X.El
  951. XHowever:
  952. X.Bl -enum -compact -offset indent
  953. X.It
  954. XAll list insertions and removals must specify the head of the list.
  955. X.It
  956. XEach head entry requires two pointers rather than one.
  957. X.It
  958. XCode size is about 15% greater and operations run about 20% slower
  959. Xthan lists.
  960. X.El
  961. X.Pp
  962. XCircular queues add the following functionality:
  963. X.Bl -enum -compact -offset indent
  964. X.It
  965. XEntries can be added at the end of a list.
  966. X.It
  967. XEntries can be added before another entry.
  968. X.It
  969. XThey may be traversed backwards, from tail to head.
  970. X.El
  971. XHowever:
  972. X.Bl -enum -compact -offset indent
  973. X.It
  974. XAll list insertions and removals must specify the head of the list.
  975. X.It
  976. XEach head entry requires two pointers rather than one.
  977. X.It
  978. XThe termination condition for traversal is more complex.
  979. X.It
  980. XCode size is about 40% greater and operations run about 45% slower
  981. Xthan lists.
  982. X.El
  983. X.Pp
  984. XIn the macro definitions,
  985. X.Fa TYPE
  986. Xis the name of a user defined structure,
  987. Xthat must contain a field of type
  988. X.Li LIST_ENTRY ,
  989. X.Li TAILQ_ENTRY ,
  990. Xor
  991. X.Li CIRCLEQ_ENTRY ,
  992. Xnamed
  993. X.Fa NAME .
  994. XThe argument
  995. X.Fa HEADNAME
  996. Xis the name of a user defined structure that must be declared
  997. Xusing the macros
  998. X.Li LIST_HEAD ,
  999. X.Li TAILQ_HEAD ,
  1000. Xor
  1001. X.Li CIRCLEQ_HEAD .
  1002. XSee the examples below for further explanation of how these
  1003. Xmacros are used.
  1004. X.Sh LISTS
  1005. XA list is headed by a structure defined by the
  1006. X.Nm LIST_HEAD
  1007. Xmacro.
  1008. XThis structure contains a single pointer to the first element
  1009. Xon the list.
  1010. XThe elements are doubly linked so that an arbitrary element can be
  1011. Xremoved without traversing the list.
  1012. XNew elements can be added to the list after an existing element or
  1013. Xat the head of the list.
  1014. XA
  1015. X.Fa LIST_HEAD
  1016. Xstructure is declared as follows:
  1017. X.Bd -literal -offset indent
  1018. XLIST_HEAD(HEADNAME, TYPE) head;
  1019. X.Ed
  1020. X.sp
  1021. Xwhere
  1022. X.Fa HEADNAME
  1023. Xis the name of the structure to be defined, and
  1024. X.Fa TYPE
  1025. Xis the type of the elements to be linked into the list.
  1026. XA pointer to the head of the list can later be declared as:
  1027. X.Bd -literal -offset indent
  1028. Xstruct HEADNAME *headp;
  1029. X.Ed
  1030. X.sp
  1031. X(The names
  1032. X.Li head
  1033. Xand
  1034. X.Li headp
  1035. Xare user selectable.)
  1036. X.Pp
  1037. XThe macro
  1038. X.Nm LIST_ENTRY
  1039. Xdeclares a structure that connects the elements in
  1040. Xthe list.
  1041. X.Pp
  1042. XThe macro
  1043. X.Nm LIST_INIT
  1044. Xinitializes the list referenced by
  1045. X.Fa head .
  1046. X.Pp
  1047. XThe macro
  1048. X.Nm LIST_INSERT_HEAD
  1049. Xinserts the new element
  1050. X.Fa elm
  1051. Xat the head of the list.
  1052. X.Pp
  1053. XThe macro
  1054. X.Nm LIST_INSERT_AFTER
  1055. Xinserts the new element
  1056. X.Fa elm
  1057. Xafter the element
  1058. X.Fa listelm .
  1059. X.Pp
  1060. XThe macro
  1061. X.Nm LIST_REMOVE
  1062. Xremoves the element
  1063. X.Fa elm
  1064. Xfrom the list.
  1065. X.Sh LIST EXAMPLE
  1066. X.Bd -literal
  1067. XLIST_HEAD(listhead, entry) head;
  1068. Xstruct listhead *headp;        /* List head. */
  1069. Xstruct entry {
  1070. X    ...
  1071. X    LIST_ENTRY(entry) entries;    /* List. */
  1072. X    ...
  1073. X} *n1, *n2, *np;
  1074. X
  1075. XLIST_INIT(&head);            /* Initialize the list. */
  1076. X
  1077. Xn1 = malloc(sizeof(struct entry));    /* Insert at the head. */
  1078. XLIST_INSERT_HEAD(&head, n1, entries);
  1079. X
  1080. Xn2 = malloc(sizeof(struct entry));    /* Insert after. */
  1081. XLIST_INSERT_AFTER(n1, n2, entries);
  1082. X                    /* Forward traversal. */
  1083. Xfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
  1084. X    np-> ...
  1085. X
  1086. Xwhile (head.lh_first != NULL)        /* Delete. */
  1087. X    LIST_REMOVE(head.lh_first, entries);
  1088. X.Ed
  1089. X.Sh TAIL QUEUES
  1090. XA tail queue is headed by a structure defined by the
  1091. X.Nm TAILQ_HEAD
  1092. Xmacro.
  1093. XThis structure contains a pair of pointers,
  1094. Xone to the first element in the tail queue and the other to
  1095. Xthe last element in the tail queue.
  1096. XThe elements are doubly linked so that an arbitrary element can be
  1097. Xremoved without traversing the tail queue.
  1098. XNew elements can be added to the tail queue after an existing element,
  1099. Xat the head of the tail queue, or at the end of the tail queue.
  1100. XA
  1101. X.Fa TAILQ_HEAD
  1102. Xstructure is declared as follows:
  1103. X.Bd -literal -offset indent
  1104. XTAILQ_HEAD(HEADNAME, TYPE) head;
  1105. X.Ed
  1106. X.sp
  1107. Xwhere
  1108. X.Li HEADNAME
  1109. Xis the name of the structure to be defined, and
  1110. X.Li TYPE
  1111. Xis the type of the elements to be linked into the tail queue.
  1112. XA pointer to the head of the tail queue can later be declared as:
  1113. X.Bd -literal -offset indent
  1114. Xstruct HEADNAME *headp;
  1115. X.Ed
  1116. X.sp
  1117. X(The names
  1118. X.Li head
  1119. Xand
  1120. X.Li headp
  1121. Xare user selectable.)
  1122. X.Pp
  1123. XThe macro
  1124. X.Nm TAILQ_ENTRY
  1125. Xdeclares a structure that connects the elements in
  1126. Xthe tail queue.
  1127. X.Pp
  1128. XThe macro
  1129. X.Nm TAILQ_INIT
  1130. Xinitializes the tail queue referenced by
  1131. X.Fa head .
  1132. X.Pp
  1133. XThe macro
  1134. X.Nm TAILQ_INSERT_HEAD
  1135. Xinserts the new element
  1136. X.Fa elm
  1137. Xat the head of the tail queue.
  1138. X.Pp
  1139. XThe macro
  1140. X.Nm TAILQ_INSERT_TAIL
  1141. Xinserts the new element
  1142. X.Fa elm
  1143. Xat the end of the tail queue.
  1144. X.Pp
  1145. XThe macro
  1146. X.Nm TAILQ_INSERT_AFTER
  1147. Xinserts the new element
  1148. X.Fa elm
  1149. Xafter the element
  1150. X.Fa listelm .
  1151. X.Pp
  1152. XThe macro
  1153. X.Nm TAILQ_REMOVE
  1154. Xremoves the element
  1155. X.Fa elm
  1156. Xfrom the tail queue.
  1157. X.Sh TAIL QUEUE EXAMPLE
  1158. X.Bd -literal
  1159. XTAILQ_HEAD(tailhead, entry) head;
  1160. Xstruct tailhead *headp;        /* Tail queue head. */
  1161. Xstruct entry {
  1162. X    ...
  1163. X    TAILQ_ENTRY(entry) entries;    /* Tail queue. */
  1164. X    ...
  1165. X} *n1, *n2, *np;
  1166. X
  1167. XTAILQ_INIT(&head);            /* Initialize the queue. */
  1168. X
  1169. Xn1 = malloc(sizeof(struct entry));    /* Insert at the head. */
  1170. XTAILQ_INSERT_HEAD(&head, n1, entries);
  1171. X
  1172. Xn1 = malloc(sizeof(struct entry));    /* Insert at the tail. */
  1173. XTAILQ_INSERT_TAIL(&head, n1, entries);
  1174. X
  1175. Xn2 = malloc(sizeof(struct entry));    /* Insert after. */
  1176. XTAILQ_INSERT_AFTER(&head, n1, n2, entries);
  1177. X                    /* Forward traversal. */
  1178. Xfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
  1179. X    np-> ...
  1180. X                    /* Delete. */
  1181. Xwhile (head.tqh_first != NULL)
  1182. X    TAILQ_REMOVE(&head, head.tqh_first, entries);
  1183. X.Ed
  1184. X.Sh CIRCULAR QUEUES
  1185. XA circular queue is headed by a structure defined by the
  1186. X.Nm CIRCLEQ_HEAD
  1187. Xmacro.
  1188. XThis structure contains a pair of pointers,
  1189. Xone to the first element in the circular queue and the other to the
  1190. Xlast element in the circular queue.
  1191. XThe elements are doubly linked so that an arbitrary element can be
  1192. Xremoved without traversing the queue.
  1193. XNew elements can be added to the queue after an existing element,
  1194. Xbefore an existing element, at the head of the queue, or at the end
  1195. Xof the queue.
  1196. XA
  1197. X.Fa CIRCLEQ_HEAD
  1198. Xstructure is declared as follows:
  1199. X.Bd -literal -offset indent
  1200. XCIRCLEQ_HEAD(HEADNAME, TYPE) head;
  1201. X.Ed
  1202. X.sp
  1203. Xwhere
  1204. X.Li HEADNAME
  1205. Xis the name of the structure to be defined, and
  1206. X.Li TYPE
  1207. Xis the type of the elements to be linked into the circular queue.
  1208. XA pointer to the head of the circular queue can later be declared as:
  1209. X.Bd -literal -offset indent
  1210. Xstruct HEADNAME *headp;
  1211. X.Ed
  1212. X.sp
  1213. X(The names
  1214. X.Li head
  1215. Xand
  1216. X.Li headp
  1217. Xare user selectable.)
  1218. X.Pp
  1219. XThe macro
  1220. X.Nm CIRCLEQ_ENTRY
  1221. Xdeclares a structure that connects the elements in
  1222. Xthe circular queue.
  1223. X.Pp
  1224. XThe macro
  1225. X.Nm CIRCLEQ_INIT
  1226. Xinitializes the circular queue referenced by
  1227. X.Fa head .
  1228. X.Pp
  1229. XThe macro
  1230. X.Nm CIRCLEQ_INSERT_HEAD
  1231. Xinserts the new element
  1232. X.Fa elm
  1233. Xat the head of the circular queue.
  1234. X.Pp
  1235. XThe macro
  1236. X.Nm CIRCLEQ_INSERT_TAIL
  1237. Xinserts the new element
  1238. X.Fa elm
  1239. Xat the end of the circular queue.
  1240. X.Pp
  1241. XThe macro
  1242. X.Nm CIRCLEQ_INSERT_AFTER
  1243. Xinserts the new element
  1244. X.Fa elm
  1245. Xafter the element
  1246. X.Fa listelm .
  1247. X.Pp
  1248. XThe macro
  1249. X.Nm CIRCLEQ_INSERT_BEFORE
  1250. Xinserts the new element
  1251. X.Fa elm
  1252. Xbefore the element
  1253. X.Fa listelm .
  1254. X.Pp
  1255. XThe macro
  1256. X.Nm CIRCLEQ_REMOVE
  1257. Xremoves the element
  1258. X.Fa elm
  1259. Xfrom the circular queue.
  1260. X.Sh CIRCULAR QUEUE EXAMPLE
  1261. X.Bd -literal
  1262. XCIRCLEQ_HEAD(circleq, entry) head;
  1263. Xstruct circleq *headp;            /* Circular queue head. */
  1264. Xstruct entry {
  1265. X    ...
  1266. X    CIRCLEQ_ENTRY entries;        /* Circular queue. */
  1267. X    ...
  1268. X} *n1, *n2, *np;
  1269. X
  1270. XCIRCLEQ_INIT(&head);            /* Initialize the circular queue. */
  1271. X
  1272. Xn1 = malloc(sizeof(struct entry));    /* Insert at the head. */
  1273. XCIRCLEQ_INSERT_HEAD(&head, n1, entries);
  1274. X
  1275. Xn1 = malloc(sizeof(struct entry));    /* Insert at the tail. */
  1276. XCIRCLEQ_INSERT_TAIL(&head, n1, entries);
  1277. X
  1278. Xn2 = malloc(sizeof(struct entry));    /* Insert after. */
  1279. XCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
  1280. X
  1281. Xn2 = malloc(sizeof(struct entry));    /* Insert before. */
  1282. XCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
  1283. X                    /* Forward traversal. */
  1284. Xfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
  1285. X    np-> ...
  1286. X                    /* Reverse traversal. */
  1287. Xfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
  1288. X    np-> ...
  1289. X                    /* Delete. */
  1290. Xwhile (head.cqh_first != (void *)&head)
  1291. X    CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
  1292. X.Ed
  1293. X.Sh HISTORY
  1294. XThe
  1295. X.Nm queue
  1296. Xfunctions first appeared in 4.4BSD.
  1297. END-of-queue.3
  1298. echo x - queue.h
  1299. sed 's/^X//' >queue.h << 'END-of-queue.h'
  1300. X/* 
  1301. X * Copyright (c) 1991, 1993
  1302. X *    The Regents of the University of California.  All rights reserved.
  1303. X *
  1304. X * Redistribution and use in source and binary forms, with or without
  1305. X * modification, are permitted provided that the following conditions
  1306. X * are met:
  1307. X * 1. Redistributions of source code must retain the above copyright
  1308. X *    notice, this list of conditions and the following disclaimer.
  1309. X * 2. Redistributions in binary form must reproduce the above copyright
  1310. X *    notice, this list of conditions and the following disclaimer in the
  1311. X *    documentation and/or other materials provided with the distribution.
  1312. X * 3. All advertising materials mentioning features or use of this software
  1313. X *    must display the following acknowledgement:
  1314. X *    This product includes software developed by the University of
  1315. X *    California, Berkeley and its contributors.
  1316. X * 4. Neither the name of the University nor the names of its contributors
  1317. X *    may be used to endorse or promote products derived from this software
  1318. X *    without specific prior written permission.
  1319. X *
  1320. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1321. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1322. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1323. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1324. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1325. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1326. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1327. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1328. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1329. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1330. X * SUCH DAMAGE.
  1331. X *
  1332. X *    @(#)queue.h    8.3 (Berkeley) 12/13/93
  1333. X */
  1334. X
  1335. X#ifndef    _QUEUE_H_
  1336. X#define    _QUEUE_H_
  1337. X
  1338. X/*
  1339. X * This file defines three types of data structures: lists, tail queues,
  1340. X * and circular queues.
  1341. X *
  1342. X * A list is headed by a single forward pointer (or an array of forward
  1343. X * pointers for a hash table header). The elements are doubly linked
  1344. X * so that an arbitrary element can be removed without a need to
  1345. X * traverse the list. New elements can be added to the list after
  1346. X * an existing element or at the head of the list. A list may only be
  1347. X * traversed in the forward direction.
  1348. X *
  1349. X * A tail queue is headed by a pair of pointers, one to the head of the
  1350. X * list and the other to the tail of the list. The elements are doubly
  1351. X * linked so that an arbitrary element can be removed without a need to
  1352. X * traverse the list. New elements can be added to the list after
  1353. X * an existing element, at the head of the list, or at the end of the
  1354. X * list. A tail queue may only be traversed in the forward direction.
  1355. X *
  1356. X * A circle queue is headed by a pair of pointers, one to the head of the
  1357. X * list and the other to the tail of the list. The elements are doubly
  1358. X * linked so that an arbitrary element can be removed without a need to
  1359. X * traverse the list. New elements can be added to the list before or after
  1360. X * an existing element, at the head of the list, or at the end of the list.
  1361. X * A circle queue may be traversed in either direction, but has a more
  1362. X * complex end of list detection.
  1363. X *
  1364. X * For details on the use of these macros, see the queue(3) manual page.
  1365. X */
  1366. X
  1367. X/*
  1368. X * List definitions.
  1369. X */
  1370. X#define LIST_HEAD(name, type)                        \
  1371. Xstruct name {                                \
  1372. X    struct type *lh_first;    /* first element */            \
  1373. X}
  1374. X
  1375. X#define LIST_ENTRY(type)                        \
  1376. Xstruct {                                \
  1377. X    struct type *le_next;    /* next element */            \
  1378. X    struct type **le_prev;    /* address of previous next element */    \
  1379. X}
  1380. X
  1381. X/*
  1382. X * List functions.
  1383. X */
  1384. X#define    LIST_INIT(head) {                        \
  1385. X    (head)->lh_first = NULL;                    \
  1386. X}
  1387. X
  1388. X#define LIST_INSERT_AFTER(listelm, elm, field) {            \
  1389. X    if (((elm)->field.le_next = (listelm)->field.le_next) != NULL)    \
  1390. X        (listelm)->field.le_next->field.le_prev =        \
  1391. X            &(elm)->field.le_next;                \
  1392. X    (listelm)->field.le_next = (elm);                \
  1393. X    (elm)->field.le_prev = &(listelm)->field.le_next;        \
  1394. X}
  1395. X
  1396. X#define LIST_INSERT_HEAD(head, elm, field) {                \
  1397. X    if (((elm)->field.le_next = (head)->lh_first) != NULL)        \
  1398. X        (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
  1399. X    (head)->lh_first = (elm);                    \
  1400. X    (elm)->field.le_prev = &(head)->lh_first;            \
  1401. X}
  1402. X
  1403. X#define LIST_REMOVE(elm, field) {                    \
  1404. X    if ((elm)->field.le_next != NULL)                \
  1405. X        (elm)->field.le_next->field.le_prev =             \
  1406. X            (elm)->field.le_prev;                \
  1407. X    *(elm)->field.le_prev = (elm)->field.le_next;            \
  1408. X}
  1409. X
  1410. X/*
  1411. X * Tail queue definitions.
  1412. X */
  1413. X#define TAILQ_HEAD(name, type)                        \
  1414. Xstruct name {                                \
  1415. X    struct type *tqh_first;    /* first element */            \
  1416. X    struct type **tqh_last;    /* addr of last next element */        \
  1417. X}
  1418. X
  1419. X#define TAILQ_ENTRY(type)                        \
  1420. Xstruct {                                \
  1421. X    struct type *tqe_next;    /* next element */            \
  1422. X    struct type **tqe_prev;    /* address of previous next element */    \
  1423. X}
  1424. X
  1425. X/*
  1426. X * Tail queue functions.
  1427. X */
  1428. X#define    TAILQ_INIT(head) {                        \
  1429. X    (head)->tqh_first = NULL;                    \
  1430. X    (head)->tqh_last = &(head)->tqh_first;                \
  1431. X}
  1432. X
  1433. X#define TAILQ_INSERT_HEAD(head, elm, field) {                \
  1434. X    if (((elm)->field.tqe_next = (head)->tqh_first) != NULL)    \
  1435. X        (elm)->field.tqe_next->field.tqe_prev =            \
  1436. X            &(elm)->field.tqe_next;                \
  1437. X    else                                \
  1438. X        (head)->tqh_last = &(elm)->field.tqe_next;        \
  1439. X    (head)->tqh_first = (elm);                    \
  1440. X    (elm)->field.tqe_prev = &(head)->tqh_first;            \
  1441. X}
  1442. X
  1443. X#define TAILQ_INSERT_TAIL(head, elm, field) {                \
  1444. X    (elm)->field.tqe_next = NULL;                    \
  1445. X    (elm)->field.tqe_prev = (head)->tqh_last;            \
  1446. X    *(head)->tqh_last = (elm);                    \
  1447. X    (head)->tqh_last = &(elm)->field.tqe_next;            \
  1448. X}
  1449. X
  1450. X#define TAILQ_INSERT_AFTER(head, listelm, elm, field) {            \
  1451. X    if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
  1452. X        (elm)->field.tqe_next->field.tqe_prev =         \
  1453. X            &(elm)->field.tqe_next;                \
  1454. X    else                                \
  1455. X        (head)->tqh_last = &(elm)->field.tqe_next;        \
  1456. X    (listelm)->field.tqe_next = (elm);                \
  1457. X    (elm)->field.tqe_prev = &(listelm)->field.tqe_next;        \
  1458. X}
  1459. X
  1460. X#define TAILQ_REMOVE(head, elm, field) {                \
  1461. X    if (((elm)->field.tqe_next) != NULL)                \
  1462. X        (elm)->field.tqe_next->field.tqe_prev =         \
  1463. X            (elm)->field.tqe_prev;                \
  1464. X    else                                \
  1465. X        (head)->tqh_last = (elm)->field.tqe_prev;        \
  1466. X    *(elm)->field.tqe_prev = (elm)->field.tqe_next;            \
  1467. X}
  1468. X
  1469. X/*
  1470. X * Circular queue definitions.
  1471. X */
  1472. X#define CIRCLEQ_HEAD(name, type)                    \
  1473. Xstruct name {                                \
  1474. X    struct type *cqh_first;        /* first element */        \
  1475. X    struct type *cqh_last;        /* last element */        \
  1476. X}
  1477. X
  1478. X#define CIRCLEQ_ENTRY(type)                        \
  1479. Xstruct {                                \
  1480. X    struct type *cqe_next;        /* next element */        \
  1481. X    struct type *cqe_prev;        /* previous element */        \
  1482. X}
  1483. X
  1484. X/*
  1485. X * Circular queue functions.
  1486. X */
  1487. X#define    CIRCLEQ_INIT(head) {                        \
  1488. X    (head)->cqh_first = (void *)(head);                \
  1489. X    (head)->cqh_last = (void *)(head);                \
  1490. X}
  1491. X
  1492. X#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) {        \
  1493. X    (elm)->field.cqe_next = (listelm)->field.cqe_next;        \
  1494. X    (elm)->field.cqe_prev = (listelm);                \
  1495. X    if ((listelm)->field.cqe_next == (void *)(head))        \
  1496. X        (head)->cqh_last = (elm);                \
  1497. X    else                                \
  1498. X        (listelm)->field.cqe_next->field.cqe_prev = (elm);    \
  1499. X    (listelm)->field.cqe_next = (elm);                \
  1500. X}
  1501. X
  1502. X#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) {        \
  1503. X    (elm)->field.cqe_next = (listelm);                \
  1504. X    (elm)->field.cqe_prev = (listelm)->field.cqe_prev;        \
  1505. X    if ((listelm)->field.cqe_prev == (void *)(head))        \
  1506. X        (head)->cqh_first = (elm);                \
  1507. X    else                                \
  1508. X        (listelm)->field.cqe_prev->field.cqe_next = (elm);    \
  1509. X    (listelm)->field.cqe_prev = (elm);                \
  1510. X}
  1511. X
  1512. X#define CIRCLEQ_INSERT_HEAD(head, elm, field) {                \
  1513. X    (elm)->field.cqe_next = (head)->cqh_first;            \
  1514. X    (elm)->field.cqe_prev = (void *)(head);                \
  1515. X    if ((head)->cqh_last == (void *)(head))                \
  1516. X        (head)->cqh_last = (elm);                \
  1517. X    else                                \
  1518. X        (head)->cqh_first->field.cqe_prev = (elm);        \
  1519. X    (head)->cqh_first = (elm);                    \
  1520. X}
  1521. X
  1522. X#define CIRCLEQ_INSERT_TAIL(head, elm, field) {                \
  1523. X    (elm)->field.cqe_next = (void *)(head);                \
  1524. X    (elm)->field.cqe_prev = (head)->cqh_last;            \
  1525. X    if ((head)->cqh_first == (void *)(head))            \
  1526. X        (head)->cqh_first = (elm);                \
  1527. X    else                                \
  1528. X        (head)->cqh_last->field.cqe_next = (elm);        \
  1529. X    (head)->cqh_last = (elm);                    \
  1530. X}
  1531. X
  1532. X#define    CIRCLEQ_REMOVE(head, elm, field) {                \
  1533. X    if ((elm)->field.cqe_next == (void *)(head))            \
  1534. X        (head)->cqh_last = (elm)->field.cqe_prev;        \
  1535. X    else                                \
  1536. X        (elm)->field.cqe_next->field.cqe_prev =            \
  1537. X            (elm)->field.cqe_prev;                \
  1538. X    if ((elm)->field.cqe_prev == (void *)(head))            \
  1539. X        (head)->cqh_first = (elm)->field.cqe_next;        \
  1540. X    else                                \
  1541. X        (elm)->field.cqe_prev->field.cqe_next =            \
  1542. X            (elm)->field.cqe_next;                \
  1543. X}
  1544. X#endif    /* !_QUEUE_H_ */
  1545. END-of-queue.h
  1546. exit
  1547.  
  1548.