home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-12-21 | 62.5 KB | 1,548 lines |
- Newsgroups: comp.sources.unix
- From: bostic@cs.berkeley.edu (Keith Bostic)
- Subject: v27i173: queue - implementations of lists, tail queues, and circular queues, Part01/01
- Message-id: <1.756504644.8164@gw.home.vix.com>
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: bostic@cs.berkeley.edu (Keith Bostic)
- Posting-Number: Volume 27, Issue 173
- Archive-Name: queue/part01
-
- Here's the final versions of the queue stuff that we talked
- about. Paul, consider it a submission for unix.sources, if
- you like.
-
- --keith
-
- [ from the manpage...
-
- DESCRIPTION
- These macros define and operate on three types of data structures: lists,
- tail queues, and circular queues. All three structures support the fol-
- lowing functionality:
- 1. Insertion of a new entry at the head of the list.
- 2. Insertion of a new entry after any element in the list.
- 3. Removal of any entry in the list.
- 4. Forward traversal through the list.
-
- --vix ]
-
- # This is a shell archive. Save it in a file, remove anything before
- # this line, and then unpack it by entering "sh file". Note, it may
- # create directories; files and directories will be owned by you and
- # have default permissions.
- #
- # This archive contains:
- #
- # queue.0
- # queue.0.ps
- # queue.3
- # queue.h
- #
- echo x - queue.0
- sed 's/^X//' >queue.0 << 'END-of-queue.0'
- XQUEUE(3) BSD Programmer's Manual QUEUE(3)
- X
- XNNAAMMEE
- X LLIISSTT__EENNTTRRYY, LLIISSTT__HHEEAADD, LLIISSTT__IINNIITT, LLIISSTT__IINNSSEERRTT__AAFFTTEERR, LLIISSTT__IINNSSEERRTT__HHEEAADD,
- X LLIISSTT__RREEMMOOVVEE, TTAAIILLQQ__EENNTTRRYY, TTAAIILLQQ__HHEEAADD, TTAAIILLQQ__IINNIITT, TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR,
- X TTAAIILLQQ__IINNSSEERRTT__HHEEAADD, TTAAIILLQQ__IINNSSEERRTT__TTAAIILL, TTAAIILLQQ__RREEMMOOVVEE, CCIIRRCCLLEEQQ__EENNTTRRYY,
- X CCIIRRCCLLEEQQ__HHEEAADD, CCIIRRCCLLEEQQ__IINNIITT, CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR, CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE,
- X CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD, CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL, CCIIRRCCLLEEQQ__RREEMMOOVVEE - implementa-
- X tions of lists, tail queues, and circular queues
- X
- XSSYYNNOOPPSSIISS
- X ##iinncclluuddee <<ssyyss//qquueeuuee..hh>>
- X
- X
- X LLIISSTT__EENNTTRRYY(_T_Y_P_E);
- X
- X LLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
- X
- X LLIISSTT__IINNIITT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
- X
- 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);
- X
- 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);
- X
- X LLIISSTT__RREEMMOOVVEE(_T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
- X
- X
- X TTAAIILLQQ__EENNTTRRYY(_T_Y_P_E);
- X
- X TTAAIILLQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
- X
- X TTAAIILLQQ__IINNIITT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
- X
- 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,
- X _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
- X
- 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);
- X
- 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);
- X
- 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);
- X
- X
- X CCIIRRCCLLEEQQ__EENNTTRRYY(_T_Y_P_E);
- X
- X CCIIRRCCLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
- X
- X CCIIRRCCLLEEQQ__IINNIITT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
- X
- 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,
- X _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
- X
- 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,
- X _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
- X
- 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);
- X
- 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);
- X
- 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);
- X
- XDDEESSCCRRIIPPTTIIOONN
- X These macros define and operate on three types of data structures: lists,
- X tail queues, and circular queues. All three structures support the fol-
- X
- X lowing functionality:
- X 1. Insertion of a new entry at the head of the list.
- X 2. Insertion of a new entry after any element in the list.
- X 3. Removal of any entry in the list.
- X 4. Forward traversal through the list.
- X
- X Lists are the simplest of the three data structures and support only the
- X above functionality.
- X
- X Tail queues add the following functionality:
- X 1. Entries can be added at the end of a list.
- X However:
- X 1. All list insertions and removals must specify the head of the
- X list.
- X 2. Each head entry requires two pointers rather than one.
- X 3. Code size is about 15% greater and operations run about 20%
- X slower than lists.
- X
- X Circular queues add the following functionality:
- X 1. Entries can be added at the end of a list.
- X 2. Entries can be added before another entry.
- X 3. They may be traversed backwards, from tail to head.
- X However:
- X 1. All list insertions and removals must specify the head of the
- X list.
- X 2. Each head entry requires two pointers rather than one.
- X 3. The termination condition for traversal is more complex.
- X 4. Code size is about 40% greater and operations run about 45%
- X slower than lists.
- X
- X In the macro definitions, _T_Y_P_E is the name of a user defined structure,
- X that must contain a field of type LIST_ENTRY, TAILQ_ENTRY, or
- X CIRCLEQ_ENTRY, named _N_A_M_E. The argument _H_E_A_D_N_A_M_E is the name of a user
- X defined structure that must be declared using the macros LIST_HEAD,
- X TAILQ_HEAD, or CIRCLEQ_HEAD. See the examples below for further explana-
- X tion of how these macros are used.
- X
- XLLIISSTTSS
- X A list is headed by a structure defined by the LLIISSTT__HHEEAADD macro. This
- X structure contains a single pointer to the first element on the list.
- X The elements are doubly linked so that an arbitrary element can be re-
- X moved without traversing the list. New elements can be added to the list
- X after an existing element or at the head of the list. A _L_I_S_T___H_E_A_D struc-
- X ture is declared as follows:
- X
- X LIST_HEAD(HEADNAME, TYPE) head;
- X
- 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
- X the type of the elements to be linked into the list. A pointer to the
- X head of the list can later be declared as:
- X
- X struct HEADNAME *headp;
- X
- X (The names head and headp are user selectable.)
- X
- X The macro LLIISSTT__EENNTTRRYY declares a structure that connects the elements in
- X the list.
- X
- X The macro LLIISSTT__IINNIITT initializes the list referenced by _h_e_a_d.
- X
- X The macro LLIISSTT__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of the
- X list.
- X
- X The macro LLIISSTT__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the element
- X _l_i_s_t_e_l_m.
- X
- X
- X The macro LLIISSTT__RREEMMOOVVEE removes the element _e_l_m from the list.
- X
- XLLIISSTT EEXXAAMMPPLLEE
- X LIST_HEAD(listhead, entry) head;
- X struct listhead *headp; /* List head. */
- X struct entry {
- X ...
- X LIST_ENTRY(entry) entries; /* List. */
- X ...
- X } *n1, *n2, *np;
- X
- X LIST_INIT(&head); /* Initialize the list. */
- X
- X n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- X LIST_INSERT_HEAD(&head, n1, entries);
- X
- X n2 = malloc(sizeof(struct entry)); /* Insert after. */
- X LIST_INSERT_AFTER(n1, n2, entries);
- X /* Forward traversal. */
- X for (np = head.lh_first; np != NULL; np = np->entries.le_next)
- X np-> ...
- X
- X while (head.lh_first != NULL) /* Delete. */
- X LIST_REMOVE(head.lh_first, entries);
- X
- XTTAAIILL QQUUEEUUEESS
- X A tail queue is headed by a structure defined by the TTAAIILLQQ__HHEEAADD macro.
- X This structure contains a pair of pointers, one to the first element in
- X the tail queue and the other to the last element in the tail queue. The
- X elements are doubly linked so that an arbitrary element can be removed
- X without traversing the tail queue. New elements can be added to the tail
- X queue after an existing element, at the head of the tail queue, or at the
- X end of the tail queue. A _T_A_I_L_Q___H_E_A_D structure is declared as follows:
- X
- X TAILQ_HEAD(HEADNAME, TYPE) head;
- X
- X where HEADNAME is the name of the structure to be defined, and TYPE is
- X the type of the elements to be linked into the tail queue. A pointer to
- X the head of the tail queue can later be declared as:
- X
- X struct HEADNAME *headp;
- X
- X (The names head and headp are user selectable.)
- X
- X The macro TTAAIILLQQ__EENNTTRRYY declares a structure that connects the elements in
- X the tail queue.
- X
- X The macro TTAAIILLQQ__IINNIITT initializes the tail queue referenced by _h_e_a_d.
- X
- X The macro TTAAIILLQQ__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of
- X the tail queue.
- X
- X The macro TTAAIILLQQ__IINNSSEERRTT__TTAAIILL inserts the new element _e_l_m at the end of the
- X tail queue.
- X
- X The macro TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the ele-
- X ment _l_i_s_t_e_l_m.
- X
- X The macro TTAAIILLQQ__RREEMMOOVVEE removes the element _e_l_m from the tail queue.
- X
- XTTAAIILL QQUUEEUUEE EEXXAAMMPPLLEE
- X TAILQ_HEAD(tailhead, entry) head;
- X struct tailhead *headp; /* Tail queue head. */
- X struct entry {
- X ...
- X TAILQ_ENTRY(entry) entries; /* Tail queue. */
- X ...
- X } *n1, *n2, *np;
- X
- X TAILQ_INIT(&head); /* Initialize the queue. */
- X
- X n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- X TAILQ_INSERT_HEAD(&head, n1, entries);
- X
- X n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
- X TAILQ_INSERT_TAIL(&head, n1, entries);
- X
- X n2 = malloc(sizeof(struct entry)); /* Insert after. */
- X TAILQ_INSERT_AFTER(&head, n1, n2, entries);
- X /* Forward traversal. */
- X for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
- X np-> ...
- X /* Delete. */
- X while (head.tqh_first != NULL)
- X TAILQ_REMOVE(&head, head.tqh_first, entries);
- X
- XCCIIRRCCUULLAARR QQUUEEUUEESS
- X A circular queue is headed by a structure defined by the CCIIRRCCLLEEQQ__HHEEAADD
- X macro. This structure contains a pair of pointers, one to the first ele-
- X ment in the circular queue and the other to the last element in the cir-
- X cular queue. The elements are doubly linked so that an arbitrary element
- X can be removed without traversing the queue. New elements can be added
- X to the queue after an existing element, before an existing element, at
- 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-
- X ture is declared as follows:
- X
- X CIRCLEQ_HEAD(HEADNAME, TYPE) head;
- X
- X where HEADNAME is the name of the structure to be defined, and TYPE is
- X the type of the elements to be linked into the circular queue. A pointer
- X to the head of the circular queue can later be declared as:
- X
- X struct HEADNAME *headp;
- X
- X (The names head and headp are user selectable.)
- X
- X The macro CCIIRRCCLLEEQQ__EENNTTRRYY declares a structure that connects the elements
- X in the circular queue.
- X
- X The macro CCIIRRCCLLEEQQ__IINNIITT initializes the circular queue referenced by _h_e_a_d.
- X
- X The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD inserts the new element _e_l_m at the head of
- X the circular queue.
- X
- X The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL inserts the new element _e_l_m at the end of
- X the circular queue.
- X
- X The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR inserts the new element _e_l_m after the ele-
- X ment _l_i_s_t_e_l_m.
- X
- X The macro CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE inserts the new element _e_l_m before the
- X element _l_i_s_t_e_l_m.
- X
- X The macro CCIIRRCCLLEEQQ__RREEMMOOVVEE removes the element _e_l_m from the circular queue.
- X
- XCCIIRRCCUULLAARR QQUUEEUUEE EEXXAAMMPPLLEE
- X CIRCLEQ_HEAD(circleq, entry) head;
- X struct circleq *headp; /* Circular queue head. */
- X struct entry {
- X ...
- X CIRCLEQ_ENTRY entries; /* Circular queue. */
- X ...
- X } *n1, *n2, *np;
- X
- X CIRCLEQ_INIT(&head); /* Initialize the circular queue. */
- X
- X n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- X CIRCLEQ_INSERT_HEAD(&head, n1, entries);
- X
- X n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
- X CIRCLEQ_INSERT_TAIL(&head, n1, entries);
- X
- X n2 = malloc(sizeof(struct entry)); /* Insert after. */
- X CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
- X
- X n2 = malloc(sizeof(struct entry)); /* Insert before. */
- X CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
- X /* Forward traversal. */
- X for (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
- X np-> ...
- X /* Reverse traversal. */
- X for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
- X np-> ...
- X /* Delete. */
- X while (head.cqh_first != (void *)&head)
- X CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
- X
- XHHIISSTTOORRYY
- X The qquueeuuee functions first appeared in 4.4BSD.
- X
- X4th Berkeley Distribution December 13, 1993 5
- END-of-queue.0
- echo x - queue.0.ps
- sed 's/^X//' >queue.0.ps << 'END-of-queue.0.ps'
- X%!PS-Adobe-3.0
- X%%Creator: groff version 1.08
- X%%DocumentNeededResources: font Times-Roman
- X%%+ font Times-Bold
- X%%+ font Courier-Bold
- X%%+ font Courier-Oblique
- X%%+ font Symbol
- X%%+ font Courier
- X%%DocumentSuppliedResources: procset grops 1.08 0
- X%%Pages: 5
- X%%PageOrder: Ascend
- X%%Orientation: Portrait
- X%%EndComments
- X%%BeginProlog
- X%%BeginResource: procset grops 1.08 0
- X/setpacking where{
- Xpop
- Xcurrentpacking
- Xtrue setpacking
- X}if
- X/grops 120 dict dup begin
- X/SC 32 def
- X/A/show load def
- X/B{0 SC 3 -1 roll widthshow}bind def
- X/C{0 exch ashow}bind def
- X/D{0 exch 0 SC 5 2 roll awidthshow}bind def
- X/E{0 rmoveto show}bind def
- X/F{0 rmoveto 0 SC 3 -1 roll widthshow}bind def
- X/G{0 rmoveto 0 exch ashow}bind def
- X/H{0 rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
- X/I{0 exch rmoveto show}bind def
- X/J{0 exch rmoveto 0 SC 3 -1 roll widthshow}bind def
- X/K{0 exch rmoveto 0 exch ashow}bind def
- X/L{0 exch rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
- X/M{rmoveto show}bind def
- X/N{rmoveto 0 SC 3 -1 roll widthshow}bind def
- X/O{rmoveto 0 exch ashow}bind def
- X/P{rmoveto 0 exch 0 SC 5 2 roll awidthshow}bind def
- X/Q{moveto show}bind def
- X/R{moveto 0 SC 3 -1 roll widthshow}bind def
- X/S{moveto 0 exch ashow}bind def
- X/T{moveto 0 exch 0 SC 5 2 roll awidthshow}bind def
- X/SF{
- Xfindfont exch
- X[exch dup 0 exch 0 exch neg 0 0]makefont
- Xdup setfont
- X[exch/setfont cvx]cvx bind def
- X}bind def
- X/MF{
- Xfindfont
- X[5 2 roll
- X0 3 1 roll
- Xneg 0 0]makefont
- Xdup setfont
- X[exch/setfont cvx]cvx bind def
- X}bind def
- X/level0 0 def
- X/RES 0 def
- X/PL 0 def
- X/LS 0 def
- X/PLG{
- Xgsave newpath clippath pathbbox grestore
- Xexch pop add exch pop
- X}bind def
- X/BP{
- X/level0 save def
- X1 setlinecap
- X1 setlinejoin
- X72 RES div dup scale
- XLS{
- X90 rotate
- X}{
- X0 PL translate
- X}ifelse
- X1 -1 scale
- X}bind def
- X/EP{
- Xlevel0 restore
- Xshowpage
- X}bind def
- X/DA{
- Xnewpath arcn stroke
- X}bind def
- X/SN{
- Xtransform
- X.25 sub exch .25 sub exch
- Xround .25 add exch round .25 add exch
- Xitransform
- X}bind def
- X/DL{
- XSN
- Xmoveto
- XSN
- Xlineto stroke
- X}bind def
- X/DC{
- Xnewpath 0 360 arc closepath
- X}bind def
- X/TM matrix def
- X/DE{
- XTM currentmatrix pop
- Xtranslate scale newpath 0 0 .5 0 360 arc closepath
- XTM setmatrix
- X}bind def
- X/RC/rcurveto load def
- X/RL/rlineto load def
- X/ST/stroke load def
- X/MT/moveto load def
- X/CL/closepath load def
- X/FL{
- Xcurrentgray exch setgray fill setgray
- X}bind def
- X/BL/fill load def
- X/LW/setlinewidth load def
- X/RE{
- Xfindfont
- Xdup maxlength 1 index/FontName known not{1 add}if dict begin
- X{
- X1 index/FID ne{def}{pop pop}ifelse
- X}forall
- X/Encoding exch def
- Xdup/FontName exch def
- Xcurrentdict end definefont pop
- X}bind def
- X/DEFS 0 def
- X/EBEGIN{
- Xmoveto
- XDEFS begin
- X}bind def
- X/EEND/end load def
- X/CNT 0 def
- X/level1 0 def
- X/PBEGIN{
- X/level1 save def
- Xtranslate
- Xdiv 3 1 roll div exch scale
- Xneg exch neg exch translate
- X0 setgray
- X0 setlinecap
- X1 setlinewidth
- X0 setlinejoin
- X10 setmiterlimit
- X[]0 setdash
- X/setstrokeadjust where{
- Xpop
- Xfalse setstrokeadjust
- X}if
- X/setoverprint where{
- Xpop
- Xfalse setoverprint
- X}if
- Xnewpath
- X/CNT countdictstack def
- Xuserdict begin
- X/showpage{}def
- X}bind def
- X/PEND{
- Xclear
- Xcountdictstack CNT sub{end}repeat
- Xlevel1 restore
- X}bind def
- Xend def
- X/setpacking where{
- Xpop
- Xsetpacking
- X}if
- X%%EndResource
- X%%IncludeResource: font Times-Roman
- X%%IncludeResource: font Times-Bold
- X%%IncludeResource: font Courier-Bold
- X%%IncludeResource: font Courier-Oblique
- X%%IncludeResource: font Symbol
- X%%IncludeResource: font Courier
- Xgrops begin/DEFS 1 dict def DEFS begin/u{.001 mul}bind def end/RES 72 def/PL
- X792 def/LS false def/ENC0[/asciicircum/asciitilde/Scaron/Zcaron/scaron/zcaron
- X/Ydieresis/trademark/quotesingle/.notdef/.notdef/.notdef/.notdef/.notdef
- X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- X/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
- X/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright/parenleft
- X/parenright/asterisk/plus/comma/hyphen/period/slash/zero/one/two/three/four
- X/five/six/seven/eight/nine/colon/semicolon/less/equal/greater/question/at/A/B/C
- 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
- X/bracketright/circumflex/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q
- X/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/tilde/.notdef/quotesinglbase
- X/guillemotleft/guillemotright/bullet/florin/fraction/perthousand/dagger
- X/daggerdbl/endash/emdash/ff/fi/fl/ffi/ffl/dotlessi/dotlessj/grave/hungarumlaut
- X/dotaccent/breve/caron/ring/ogonek/quotedblleft/quotedblright/oe/lslash
- X/quotedblbase/OE/Lslash/.notdef/exclamdown/cent/sterling/currency/yen/brokenbar
- X/section/dieresis/copyright/ordfeminine/guilsinglleft/logicalnot/minus
- X/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu
- X/paragraph/periodcentered/cedilla/onesuperior/ordmasculine/guilsinglright
- X/onequarter/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumflex/Atilde
- X/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute
- X/Icircumflex/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
- X/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls
- X/agrave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/egrave/eacute
- X/ecircumflex/edieresis/igrave/iacute/icircumflex/idieresis/eth/ntilde/ograve
- X/oacute/ocircumflex/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex
- X/udieresis/yacute/thorn/ydieresis]def/Courier@0 ENC0/Courier RE
- X/Courier-Oblique@0 ENC0/Courier-Oblique RE/Courier-Bold@0 ENC0/Courier-Bold RE
- X/Times-Bold@0 ENC0/Times-Bold RE/Times-Roman@0 ENC0/Times-Roman RE
- X%%EndProlog
- X%%Page: 1 1
- X%%BeginPageSetup
- XBP
- X%%EndPageSetup
- X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
- X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
- X/F1 10/Times-Bold@0 SF -.2(NA)72 108 S(ME).2 E/F2 10/Courier-Bold@0 SF
- X(LIST_ENTRY)102 120 Q F0(,)A F2(LIST_HEAD)179.375 120 Q F0(,)A F2(LIST_INIT)
- X250.75 120 Q F0(,)A F2(LIST_INSERT_AFTER)322.125 120 Q F0(,)A F2
- X(LIST_INSERT_HEAD)441.5 120 Q F0(,)A F2(LIST_REMOVE)102 132 Q F0(,)A F2
- X(TAILQ_ENTRY)186.875 132 Q F0(,)A F2(TAILQ_HEAD)271.75 132 Q F0(,)A F2
- X(TAILQ_INIT)350.625 132 Q F0(,)A F2(TAILQ_INSERT_AFTER)429.5 132 Q F0(,)A F2
- X(TAILQ_INSERT_HEAD)102 144 Q F0(,)A F2(TAILQ_INSERT_TAIL)231.167 144 Q F0(,)A
- XF2(TAILQ_REMOVE)360.334 144 Q F0(,)A F2(CIRCLEQ_ENTRY)459.5 144 Q F0(,)A F2
- X(CIRCLEQ_HEAD)102 156 Q F0(,)A F2(CIRCLEQ_INIT)189.166 156 Q F0(,)A F2
- X(CIRCLEQ_INSERT_AFTER)276.333 156 Q F0(,)A F2(CIRCLEQ_INSERT_BEFORE)411.5 156 Q
- XF0(,)A F2(CIRCLEQ_INSERT_HEAD)102 168 Q F0(,)A F2(CIRCLEQ_INSERT_TAIL)3.624 E
- XF0(,)A F2(CIRCLEQ_REMOVE)3.624 E F0 3.623<ad69>3.623 G 1.123
- X(mplementations of lists,)441.914 168 R(tail queues, and circular queues)102
- X180 Q F1(SYNOPSIS)72 204 Q F2(#include <sys/queue.h>)102 216 Q(LIST_ENTRY)102
- X246 Q F0(\()A/F3 10/Courier-Oblique@0 SF(TYPE)A F0(\);)A F2(LIST_HEAD)102 264 Q
- XF0(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)4.166 E F0(\);)A F2(LIST_INIT)102
- X282 Q F0(\()A F3(LIST_HEAD)A/F4 10/Symbol SF(*)6 E F3(head)A F0(\);)A F2
- X(LIST_INSERT_AFTER)102 300 Q F0(\()A F3(LIST_ENTRY)A F4(*)6 E F3(listelm)A F0
- X(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(LIST_ENTRY NAME)
- X4.166 E F0(\);)A F2(LIST_INSERT_HEAD)102 318 Q F0(\()A F3(LIST_HEAD)A F4(*)6 E
- XF3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
- X(LIST_ENTRY NAME)4.166 E F0(\);)A F2(LIST_REMOVE)102 336 Q F0(\()A F3(TYPE)A F4
- X(*)6 E F3(elm)A F0(,)1.666 E F3(LIST_ENTRY NAME)4.166 E F0(\);)A F2
- X(TAILQ_ENTRY)102 366 Q F0(\()A F3(TYPE)A F0(\);)A F2(TAILQ_HEAD)102 384 Q F0
- X(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)4.166 E F0(\);)A F2(TAILQ_INIT)102 402
- XQ F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(\);)A F2(TAILQ_INSERT_AFTER)102
- X420 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E
- XF4(*)6 E F3(listelm)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666
- XE F3(TAILQ_ENTRY NAME)151.666 432 Q F0(\);)A F2(TAILQ_INSERT_HEAD)102 450 Q F0
- X(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E
- XF3(elm)A F0(,)1.666 E F3(TAILQ_ENTRY NAME)4.166 E F0(\);)A F2
- X(TAILQ_INSERT_TAIL)102 468 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3(head)A F0(,)
- X1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(TAILQ_ENTRY NAME)
- X4.166 E F0(\);)A F2(TAILQ_REMOVE)102 486 Q F0(\()A F3(TAILQ_HEAD)A F4(*)6 E F3
- X(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
- X(TAILQ_ENTRY NAME)4.166 E F0(\);)A F2(CIRCLEQ_ENTRY)102 516 Q F0(\()A F3(TYPE)A
- XF0(\);)A F2(CIRCLEQ_HEAD)102 534 Q F0(\()A F3(HEADNAME)A F0(,)1.666 E F3(TYPE)
- X4.166 E F0(\);)A F2(CIRCLEQ_INIT)102 552 Q F0(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E
- XF3(head)A F0(\);)A F2(CIRCLEQ_INSERT_AFTER)102 570 Q F0(\()A F3(CIRCLEQ_HEAD)A
- XF4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(listelm)A F0(,)
- X1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)
- X151.666 582 Q F0(\);)A F2(CIRCLEQ_INSERT_BEFORE)102 600 Q F0(\()A F3
- X(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3
- X(listelm)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
- X(CIRCLEQ_ENTRY NAME)151.666 612 Q F0(\);)A F2(CIRCLEQ_INSERT_HEAD)102 630 Q F0
- X(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6
- XE F3(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A F2
- X(CIRCLEQ_INSERT_TAIL)102 648 Q F0(\()A F3(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0
- X(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3(elm)A F0(,)1.666 E F3
- X(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A F2(CIRCLEQ_REMOVE)102 666 Q F0(\()A F3
- X(CIRCLEQ_HEAD)A F4(*)6 E F3(head)A F0(,)1.666 E F3(TYPE)4.166 E F4(*)6 E F3
- X(elm)A F0(,)1.666 E F3(CIRCLEQ_ENTRY NAME)4.166 E F0(\);)A(4th Berk)72 750 Q
- X(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F
- X(13, 1993)2.5 E(1)535 750 Q EP
- X%%Page: 2 2
- X%%BeginPageSetup
- XBP
- X%%EndPageSetup
- X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
- X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
- X/F1 10/Times-Bold@0 SF(DESCRIPTION)72 96 Q F0 .264(These macros de\214ne and o\
- Xperate on three types of data structures: lists, tail queues, and circular que\
- Xues.)102 108 R(All)5.263 E(three structures support the follo)102 120 Q
- X(wing functionality:)-.25 E 10(1. Insertion)132 132 R(of a ne)2.5 E 2.5(we)-.25
- XG(ntry at the head of the list.)231.17 132 Q 10(2. Insertion)132 144 R(of a ne)
- X2.5 E 2.5(we)-.25 G(ntry after an)231.17 144 Q 2.5(ye)-.15 G
- X(lement in the list.)291.83 144 Q 10(3. Remo)132 156 R -.25(va)-.15 G 2.5(lo)
- 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
- X(4. F)132 168 R(orw)-.15 E(ard tra)-.1 E -.15(ve)-.2 G(rsal through the list.)
- X.15 E
- X(Lists are the simplest of the three data structures and support only the abo)
- X102 186 Q .3 -.15(ve f)-.15 H(unctionality).15 E(.)-.65 E -.8(Ta)102 204 S
- X(il queues add the follo).8 E(wing functionality:)-.25 E 10(1. Entries)132 216
- XR(can be added at the end of a list.)2.5 E(Ho)102 228 Q(we)-.25 E -.15(ve)-.25
- XG(r:).15 E 10(1. All)132 240 R(list insertions and remo)2.5 E -.25(va)-.15 G
- X(ls must specify the head of the list.).25 E 10(2. Each)132 252 R
- X(head entry requires tw)2.5 E 2.5(op)-.1 G(ointers rather than one.)276.03 252
- XQ 10(3. Code)132 264 R
- X(size is about 15% greater and operations run about 20% slo)2.5 E
- X(wer than lists.)-.25 E(Circular queues add the follo)102 282 Q
- X(wing functionality:)-.25 E 10(1. Entries)132 294 R
- X(can be added at the end of a list.)2.5 E 10(2. Entries)132 306 R
- X(can be added before another entry)2.5 E(.)-.65 E 10(3. The)132 318 R 2.5(ym)
- X-.15 G(ay be tra)182.68 318 Q -.15(ve)-.2 G(rsed backw).15 E
- X(ards, from tail to head.)-.1 E(Ho)102 330 Q(we)-.25 E -.15(ve)-.25 G(r:).15 E
- X10(1. All)132 342 R(list insertions and remo)2.5 E -.25(va)-.15 G
- X(ls must specify the head of the list.).25 E 10(2. Each)132 354 R
- X(head entry requires tw)2.5 E 2.5(op)-.1 G(ointers rather than one.)276.03 354
- XQ 10(3. The)132 366 R(termination condition for tra)2.5 E -.15(ve)-.2 G
- X(rsal is more comple).15 E(x.)-.15 E 10(4. Code)132 378 R
- X(size is about 40% greater and operations run about 45% slo)2.5 E
- X(wer than lists.)-.25 E 1.455(In the macro de\214nitions,)102 396 R/F2 10
- X/Courier-Oblique@0 SF(TYPE)3.955 E F0 1.456(is the name of a user de\214ned st\
- Xructure, that must contain a \214eld of type)3.956 F/F3 10/Courier@0 SF
- X(LIST_ENTRY)102 408 Q F0(,)A F3(TAILQ_ENTRY)4.498 E F0 4.498(,o)C(r)246.996 408
- XQ F3(CIRCLEQ_ENTRY)4.498 E F0 4.498(,n)C(amed)344.822 408 Q F2(NAME)4.498 E F0
- X4.498(.T)C 1.998(he ar)408.088 408 R(gument)-.18 E F2(HEADNAME)4.498 E F0 1.998
- X(is the)4.498 F 1.141
- X(name of a user de\214ned structure that must be declared using the macros)102
- X420 R F3(LIST_HEAD)3.642 E F0(,)A F3(TAILQ_HEAD)3.642 E F0 3.642(,o)C(r)536.67
- X420 Q F3(CIRCLEQ_HEAD)102 432 Q F0 2.5(.S)C(ee the e)184.56 432 Q(xamples belo)
- X-.15 E 2.5(wf)-.25 G(or further e)280.8 432 Q(xplanation of ho)-.15 E 2.5(wt)
- X-.25 G(hese macros are used.)403.43 432 Q F1(LISTS)72 456 Q F0 2.664(Al)102 468
- XS .164(ist is headed by a structure de\214ned by the)114.664 468 R/F4 10
- X/Courier-Bold@0 SF(LIST_HEAD)2.663 E F0 2.663(macro. This)2.663 F .163
- X(structure contains a single pointer to)2.663 F 1.149
- X(the \214rst element on the list.)102 480 R 1.149(The elements are doubly link)
- X6.149 F 1.15(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G
- X(d).15 E .441(without tra)102 492 R -.15(ve)-.2 G .441(rsing the list.).15 F
- X(Ne)5.441 E 2.941(we)-.25 G .441(lements can be added to the list after an e)
- X239.425 492 R .441(xisting element or at the head of)-.15 F(the list.)102 504 Q
- X(A)5 E F2(LIST_HEAD)2.5 E F0(structure is declared as follo)2.5 E(ws:)-.25 E F3
- X(LIST_HEAD\(HEADNAME, TYPE\) head;)132 522 Q F0(where)102 546 Q F2(HEADNAME)
- X3.622 E F0 1.122(is the name of the structure to be de\214ned, and)3.622 F F2
- X(TYPE)3.623 E F0 1.123(is the type of the elements to be)3.623 F(link)102 558 Q
- X(ed into the list.)-.1 E 2.5(Ap)5 G
- X(ointer to the head of the list can later be declared as:)196.63 558 Q F3
- X(struct HEADNAME)132 576 Q/F5 10/Symbol SF(*)6 E F3(headp;)A F0(\(The names)102
- X600 Q F3(head)2.5 E F0(and)2.5 E F3(headp)2.5 E F0(are user selectable.\))2.5 E
- X(The macro)102 618 Q F4(LIST_ENTRY)2.5 E F0
- X(declares a structure that connects the elements in the list.)2.5 E(The macro)
- X102 636 Q F4(LIST_INIT)2.5 E F0(initializes the list referenced by)2.5 E F2
- X(head)2.5 E F0(.)A(The macro)102 654 Q F4(LIST_INSERT_HEAD)2.5 E F0
- X(inserts the ne)2.5 E 2.5(we)-.25 G(lement)312.72 654 Q F2(elm)2.5 E F0
- X(at the head of the list.)2.5 E(The macro)102 672 Q F4(LIST_INSERT_AFTER)2.5 E
- XF0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)318.72 672 Q F2(elm)2.5 E F0
- X(after the element)2.5 E F2(listelm)2.5 E F0(.)A(The macro)102 690 Q F4
- X(LIST_REMOVE)2.5 E F0(remo)2.5 E -.15(ve)-.15 G 2.5(st).15 G(he element)254.9
- 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)
- X-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(2)535 750
- XQ EP
- X%%Page: 3 3
- X%%BeginPageSetup
- XBP
- X%%EndPageSetup
- X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
- X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
- X/F1 10/Times-Bold@0 SF 1.666(LIST EXAMPLE)72 96 R/F2 10/Courier@0 SF
- X(LIST_HEAD\(listhead, entry\) head;)102 126 Q(struct listhead)102 138 Q/F3 10
- X/Symbol SF(*)6 E F2 82(headp; /)B F3(*)A F2(List head.)6 E F3(*)6 E F2(/)A
- X(struct entry {)102 150 Q(...)147 162 Q(LIST_ENTRY\(entry\) entries;)147 174 Q
- X(/)327 174 Q F3(*)A F2(List.)6 E F3(*)6 E F2(/)A(...)147 186 Q(})102 198 Q F3
- X(*)6 E F2(n1,)A F3(*)6 E F2(n2,)A F3(*)6 E F2(np;)A 117(LIST_INIT\(&head\); /)
- X102 222 R F3(*)A F2(Initialize the list.)6 E F3(*)6 E F2(/)A
- X(n1 = malloc\(sizeof\(struct entry\)\);)102 246 Q(/)327 246 Q F3(*)A F2
- X(Insert at the head.)6 E F3(*)6 E F2(/)A
- X(LIST_INSERT_HEAD\(&head, n1, entries\);)102 258 Q
- X(n2 = malloc\(sizeof\(struct entry\)\);)102 282 Q(/)327 282 Q F3(*)A F2
- X(Insert after.)6 E F3(*)6 E F2(/)A(LIST_INSERT_AFTER\(n1, n2, entries\);)102
- X294 Q(/)327 306 Q F3(*)A F2(Forward traversal.)6 E F3(*)6 E F2(/)A
- X(for \(np = head.lh_first; np != NULL; np = np->entries.le_next\))102 318 Q
- X(np-> ...)147 330 Q(while \(head.lh_first != NULL\))102 354 Q(/)327 354 Q F3(*)
- XA F2(Delete.)6 E F3(*)6 E F2(/)A(LIST_REMOVE\(head.lh_first, entries\);)147 366
- XQ F1 -.9(TA)72 390 S 1.666(IL Q).9 F(UEUES)-.1 E F0 2.98(At)102 402 S .48
- X(ail queue is headed by a structure de\214ned by the)114.98 402 R/F4 10
- X/Courier-Bold@0 SF(TAILQ_HEAD)2.979 E F0 2.979(macro. This)2.979 F .479
- X(structure contains a pair of)2.979 F .227(pointers, one to the \214rst elemen\
- Xt in the tail queue and the other to the last element in the tail queue.)102
- X414 R .228(The ele-)5.228 F .387(ments are doubly link)102 426 R .387
- X(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G 2.887(dw).15
- XG .387(ithout tra)390.075 426 R -.15(ve)-.2 G .387(rsing the tail queue.).15 F
- X(Ne)5.387 E(w)-.25 E .45(elements can be added to the tail queue after an e)102
- X438 R .451(xisting element, at the head of the tail queue, or at the end)-.15 F
- X(of the tail queue.)102 450 Q(A)5 E/F5 10/Courier-Oblique@0 SF(TAILQ_HEAD)2.5 E
- XF0(structure is declared as follo)2.5 E(ws:)-.25 E F2
- X(TAILQ_HEAD\(HEADNAME, TYPE\) head;)132 468 Q F0(where)102 492 Q F2(HEADNAME)
- X3.623 E F0 1.123(is the name of the structure to be de\214ned, and)3.623 F F2
- X(TYPE)3.622 E F0 1.122(is the type of the elements to be)3.622 F(link)102 504 Q
- X(ed into the tail queue.)-.1 E 2.5(Ap)5 G
- X(ointer to the head of the tail queue can later be declared as:)223.56 504 Q F2
- X(struct HEADNAME)132 522 Q F3(*)6 E F2(headp;)A F0(\(The names)102 546 Q F2
- X(head)2.5 E F0(and)2.5 E F2(headp)2.5 E F0(are user selectable.\))2.5 E
- X(The macro)102 564 Q F4(TAILQ_ENTRY)2.5 E F0
- X(declares a structure that connects the elements in the tail queue.)2.5 E
- X(The macro)102 582 Q F4(TAILQ_INIT)2.5 E F0
- X(initializes the tail queue referenced by)2.5 E F5(head)2.5 E F0(.)A(The macro)
- X102 600 Q F4(TAILQ_INSERT_HEAD)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G
- X(lement)318.72 600 Q F5(elm)2.5 E F0(at the head of the tail queue.)2.5 E
- X(The macro)102 618 Q F4(TAILQ_INSERT_TAIL)2.5 E F0(inserts the ne)2.5 E 2.5(we)
- X-.25 G(lement)318.72 618 Q F5(elm)2.5 E F0(at the end of the tail queue.)2.5 E
- X(The macro)102 636 Q F4(TAILQ_INSERT_AFTER)2.5 E F0(inserts the ne)2.5 E 2.5
- X(we)-.25 G(lement)324.72 636 Q F5(elm)2.5 E F0(after the element)2.5 E F5
- X(listelm)2.5 E F0(.)A(The macro)102 654 Q F4(TAILQ_REMOVE)2.5 E F0(remo)2.5 E
- X-.15(ve)-.15 G 2.5(st).15 G(he element)260.9 654 Q F5(elm)2.5 E F0
- X(from the tail queue.)2.5 E F1 -.9(TA)72 678 S 1.666(IL Q).9 F 1.666
- X(UEUE EXAMPLE)-.1 F F0(4th Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85
- X750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(3)535 750 Q EP
- X%%Page: 4 4
- X%%BeginPageSetup
- XBP
- X%%EndPageSetup
- X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
- X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
- X/F1 10/Courier@0 SF(TAILQ_HEAD\(tailhead, entry\) head;)102 96 Q
- X(struct tailhead)102 108 Q/F2 10/Symbol SF(*)6 E F1 82(headp; /)B F2(*)A F1
- X(Tail queue head.)6 E F2(*)6 E F1(/)A(struct entry {)102 120 Q(...)147 132 Q
- X(TAILQ_ENTRY\(entry\) entries;)147 144 Q(/)327 144 Q F2(*)A F1(Tail queue.)6 E
- XF2(*)6 E F1(/)A(...)147 156 Q(})102 168 Q F2(*)6 E F1(n1,)A F2(*)6 E F1(n2,)A
- XF2(*)6 E F1(np;)A 111(TAILQ_INIT\(&head\); /)102 192 R F2(*)A F1
- X(Initialize the queue.)6 E F2(*)6 E F1(/)A
- X(n1 = malloc\(sizeof\(struct entry\)\);)102 216 Q(/)327 216 Q F2(*)A F1
- X(Insert at the head.)6 E F2(*)6 E F1(/)A
- X(TAILQ_INSERT_HEAD\(&head, n1, entries\);)102 228 Q
- X(n1 = malloc\(sizeof\(struct entry\)\);)102 252 Q(/)327 252 Q F2(*)A F1
- X(Insert at the tail.)6 E F2(*)6 E F1(/)A
- X(TAILQ_INSERT_TAIL\(&head, n1, entries\);)102 264 Q
- X(n2 = malloc\(sizeof\(struct entry\)\);)102 288 Q(/)327 288 Q F2(*)A F1
- X(Insert after.)6 E F2(*)6 E F1(/)A
- X(TAILQ_INSERT_AFTER\(&head, n1, n2, entries\);)102 300 Q(/)327 312 Q F2(*)A F1
- X(Forward traversal.)6 E F2(*)6 E F1(/)A
- X(for \(np = head.tqh_first; np != NULL; np = np->entries.tqe_next\))102 324 Q
- X(np-> ...)147 336 Q(/)327 348 Q F2(*)A F1(Delete.)6 E F2(*)6 E F1(/)A
- X(while \(head.tqh_first != NULL\))102 360 Q
- X(TAILQ_REMOVE\(&head, head.tqh_first, entries\);)147 372 Q/F3 10/Times-Bold@0
- XSF 1.666(CIRCULAR Q)72 396 R(UEUES)-.1 E F0 2.984(Ac)102 408 S .484
- X(ircular queue is headed by a structure de\214ned by the)116.644 408 R/F4 10
- X/Courier-Bold@0 SF(CIRCLEQ_HEAD)2.985 E F0 2.985(macro. This)2.985 F .485
- X(structure contains a)2.985 F .358(pair of pointers, one to the \214rst elemen\
- Xt in the circular queue and the other to the last element in the circular)102
- X420 R 3.33(queue. The)102 432 R .83(elements are doubly link)3.33 F .83
- X(ed so that an arbitrary element can be remo)-.1 F -.15(ve)-.15 G 3.33(dw).15 G
- X.83(ithout tra)458.14 432 R -.15(ve)-.2 G .83(rsing the).15 F 2.796(queue. Ne)
- X102 444 R 2.796(we)-.25 G .296(lements can be added to the queue after an e)
- X159.542 444 R .295(xisting element, before an e)-.15 F .295
- X(xisting element, at the)-.15 F(head of the queue, or at the end of the queue.)
- X102 456 Q(A)5 E/F5 10/Courier-Oblique@0 SF(CIRCLEQ_HEAD)2.5 E F0
- X(structure is declared as follo)2.5 E(ws:)-.25 E F1
- X(CIRCLEQ_HEAD\(HEADNAME, TYPE\) head;)132 474 Q F0(where)102 498 Q F1(HEADNAME)
- X3.622 E F0 1.122(is the name of the structure to be de\214ned, and)3.622 F F1
- X(TYPE)3.623 E F0 1.123(is the type of the elements to be)3.623 F(link)102 510 Q
- X(ed into the circular queue.)-.1 E 2.5(Ap)5 G
- X(ointer to the head of the circular queue can later be declared as:)241.32 510
- XQ F1(struct HEADNAME)132 528 Q F2(*)6 E F1(headp;)A F0(\(The names)102 552 Q F1
- X(head)2.5 E F0(and)2.5 E F1(headp)2.5 E F0(are user selectable.\))2.5 E
- X(The macro)102 570 Q F4(CIRCLEQ_ENTRY)2.5 E F0
- X(declares a structure that connects the elements in the circular queue.)2.5 E
- X(The macro)102 588 Q F4(CIRCLEQ_INIT)2.5 E F0
- X(initializes the circular queue referenced by)2.5 E F5(head)2.5 E F0(.)A
- X(The macro)102 606 Q F4(CIRCLEQ_INSERT_HEAD)2.5 E F0(inserts the ne)2.5 E 2.5
- X(we)-.25 G(lement)330.72 606 Q F5(elm)2.5 E F0
- X(at the head of the circular queue.)2.5 E(The macro)102 624 Q F4
- X(CIRCLEQ_INSERT_TAIL)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)330.72
- X624 Q F5(elm)2.5 E F0(at the end of the circular queue.)2.5 E(The macro)102 642
- XQ F4(CIRCLEQ_INSERT_AFTER)2.5 E F0(inserts the ne)2.5 E 2.5(we)-.25 G(lement)
- X336.72 642 Q F5(elm)2.5 E F0(after the element)2.5 E F5(listelm)2.5 E F0(.)A
- X(The macro)102 660 Q F4(CIRCLEQ_INSERT_BEFORE)2.5 E F0(inserts the ne)2.5 E 2.5
- X(we)-.25 G(lement)342.72 660 Q F5(elm)2.5 E F0(before the element)2.5 E F5
- X(listelm)2.5 E F0(.)A(The macro)102 678 Q F4(CIRCLEQ_REMOVE)2.5 E F0(remo)2.5 E
- X-.15(ve)-.15 G 2.5(st).15 G(he element)272.9 678 Q F5(elm)2.5 E F0
- X(from the circular queue.)2.5 E(4th Berk)72 750 Q(ele)-.1 E 2.5(yD)-.15 G
- X(istrib)132.85 750 Q 90.435(ution December)-.2 F(13, 1993)2.5 E(4)535 750 Q EP
- X%%Page: 5 5
- X%%BeginPageSetup
- XBP
- X%%EndPageSetup
- X/F0 10/Times-Roman@0 SF -.1(QU)72 48 S -.834(EUE \( 3 \)).1 F(BSD Programmer')
- X250.17 48 Q 2.5(sM)-.55 G 125.232(anual Q)340.17 48 R -.834(UEUE \( 3 \))-.1 F
- X/F1 10/Times-Bold@0 SF 1.666(CIRCULAR Q)72 96 R 1.666(UEUE EXAMPLE)-.1 F/F2 10
- X/Courier@0 SF(CIRCLEQ_HEAD\(circleq, entry\) head;)102 126 Q(struct circleq)102
- X138 Q/F3 10/Symbol SF(*)6 E F2 88(headp; /)B F3(*)A F2(Circular queue head.)6 E
- XF3(*)6 E F2(/)A(struct entry {)102 150 Q(...)147 162 Q(CIRCLEQ_ENTRY entries;)
- X147 174 Q(/)327 174 Q F3(*)A F2(Circular queue.)6 E F3(*)6 E F2(/)A(...)147 186
- XQ(})102 198 Q F3(*)6 E F2(n1,)A F3(*)6 E F2(n2,)A F3(*)6 E F2(np;)A 99
- X(CIRCLEQ_INIT\(&head\); /)102 222 R F3(*)A F2(Initialize the circular queue.)6
- XE F3(*)6 E F2(/)A(n1 = malloc\(sizeof\(struct entry\)\);)102 246 Q(/)327 246 Q
- XF3(*)A F2(Insert at the head.)6 E F3(*)6 E F2(/)A
- X(CIRCLEQ_INSERT_HEAD\(&head, n1, entries\);)102 258 Q
- X(n1 = malloc\(sizeof\(struct entry\)\);)102 282 Q(/)327 282 Q F3(*)A F2
- X(Insert at the tail.)6 E F3(*)6 E F2(/)A
- X(CIRCLEQ_INSERT_TAIL\(&head, n1, entries\);)102 294 Q
- X(n2 = malloc\(sizeof\(struct entry\)\);)102 318 Q(/)327 318 Q F3(*)A F2
- X(Insert after.)6 E F3(*)6 E F2(/)A
- X(CIRCLEQ_INSERT_AFTER\(&head, n1, n2, entries\);)102 330 Q
- X(n2 = malloc\(sizeof\(struct entry\)\);)102 354 Q(/)327 354 Q F3(*)A F2
- X(Insert before.)6 E F3(*)6 E F2(/)A
- X(CIRCLEQ_INSERT_BEFORE\(&head, n1, n2, entries\);)102 366 Q(/)327 378 Q F3(*)A
- XF2(Forward traversal.)6 E F3(*)6 E F2(/)A
- X(for \(np = head.cqh_first; np != \(void)102 390 Q F3(*)6 E F2
- X(\)&head; np = np->entries.cqe_next\))A(np-> ...)147 402 Q(/)327 414 Q F3(*)A
- XF2(Reverse traversal.)6 E F3(*)6 E F2(/)A
- X(for \(np = head.cqh_last; np != \(void)102 426 Q F3(*)6 E F2
- X(\)&head; np = np->entries.cqe_prev\))A(np-> ...)147 438 Q(/)327 450 Q F3(*)A
- XF2(Delete.)6 E F3(*)6 E F2(/)A(while \(head.cqh_first != \(void)102 462 Q F3(*)
- X6 E F2(\)&head\))A(CIRCLEQ_REMOVE\(&head, head.cqh_first, entries\);)147 474 Q
- XF1(HIST)72 498 Q(OR)-.18 E(Y)-.35 E F0(The)102 510 Q/F4 10/Courier-Bold@0 SF
- X(queue)2.5 E F0(functions \214rst appeared in 4.4BSD.)2.5 E(4th Berk)72 750 Q
- X(ele)-.1 E 2.5(yD)-.15 G(istrib)132.85 750 Q 90.435(ution December)-.2 F
- X(13, 1993)2.5 E(5)535 750 Q EP
- X%%Trailer
- Xend
- X%%EOF
- END-of-queue.0.ps
- echo x - queue.3
- sed 's/^X//' >queue.3 << 'END-of-queue.3'
- X.\" Copyright (c) 1993 The Regents of the University of California.
- X.\" All rights reserved.
- X.\"
- X.\" Redistribution and use in source and binary forms, with or without
- X.\" modification, are permitted provided that the following conditions
- X.\" are met:
- X.\" 1. Redistributions of source code must retain the above copyright
- X.\" notice, this list of conditions and the following disclaimer.
- X.\" 2. Redistributions in binary form must reproduce the above copyright
- X.\" notice, this list of conditions and the following disclaimer in the
- X.\" documentation and/or other materials provided with the distribution.
- X.\" 3. All advertising materials mentioning features or use of this software
- X.\" must display the following acknowledgement:
- X.\" This product includes software developed by the University of
- X.\" California, Berkeley and its contributors.
- X.\" 4. Neither the name of the University nor the names of its contributors
- X.\" may be used to endorse or promote products derived from this software
- X.\" without specific prior written permission.
- X.\"
- X.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- X.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- X.\" SUCH DAMAGE.
- X.\"
- X.\" @(#)queue.3 8.1 (Berkeley) 12/13/93
- X.\"
- X.Dd "December 13, 1993"
- X.Dt QUEUE 3
- X.Os BSD 4
- X.Sh NAME
- X.Nm LIST_ENTRY ,
- X.Nm LIST_HEAD ,
- X.Nm LIST_INIT ,
- X.Nm LIST_INSERT_AFTER ,
- X.Nm LIST_INSERT_HEAD ,
- X.Nm LIST_REMOVE ,
- X.Nm TAILQ_ENTRY ,
- X.Nm TAILQ_HEAD ,
- X.Nm TAILQ_INIT ,
- X.Nm TAILQ_INSERT_AFTER ,
- X.Nm TAILQ_INSERT_HEAD ,
- X.Nm TAILQ_INSERT_TAIL ,
- X.Nm TAILQ_REMOVE ,
- X.Nm CIRCLEQ_ENTRY ,
- X.Nm CIRCLEQ_HEAD ,
- X.Nm CIRCLEQ_INIT ,
- X.Nm CIRCLEQ_INSERT_AFTER ,
- X.Nm CIRCLEQ_INSERT_BEFORE ,
- X.Nm CIRCLEQ_INSERT_HEAD ,
- X.Nm CIRCLEQ_INSERT_TAIL ,
- X.Nm CIRCLEQ_REMOVE
- X.Nd implementations of lists, tail queues, and circular queues
- X.Sh SYNOPSIS
- X.Fd #include <sys/queue.h>
- X.sp
- X.Fn LIST_ENTRY "TYPE"
- X.Fn LIST_HEAD "HEADNAME" "TYPE"
- X.Fn LIST_INIT "LIST_HEAD *head"
- X.Fn LIST_INSERT_AFTER "LIST_ENTRY *listelm" "TYPE *elm" "LIST_ENTRY NAME"
- X.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
- X.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
- X.sp
- X.Fn TAILQ_ENTRY "TYPE"
- X.Fn TAILQ_HEAD "HEADNAME" "TYPE"
- X.Fn TAILQ_INIT "TAILQ_HEAD *head"
- X.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
- X.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
- X.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
- X.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
- X.sp
- X.Fn CIRCLEQ_ENTRY "TYPE"
- X.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
- X.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
- X.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
- X.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
- X.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
- X.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
- X.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME"
- X.Sh DESCRIPTION
- XThese macros define and operate on three types of data structures:
- Xlists, tail queues, and circular queues.
- XAll three structures support the following functionality:
- X.Bl -enum -compact -offset indent
- X.It
- XInsertion of a new entry at the head of the list.
- X.It
- XInsertion of a new entry after any element in the list.
- X.It
- XRemoval of any entry in the list.
- X.It
- XForward traversal through the list.
- X.El
- X.Pp
- XLists are the simplest of the three data structures and support
- Xonly the above functionality.
- X.Pp
- XTail queues add the following functionality:
- X.Bl -enum -compact -offset indent
- X.It
- XEntries can be added at the end of a list.
- X.El
- XHowever:
- X.Bl -enum -compact -offset indent
- X.It
- XAll list insertions and removals must specify the head of the list.
- X.It
- XEach head entry requires two pointers rather than one.
- X.It
- XCode size is about 15% greater and operations run about 20% slower
- Xthan lists.
- X.El
- X.Pp
- XCircular queues add the following functionality:
- X.Bl -enum -compact -offset indent
- X.It
- XEntries can be added at the end of a list.
- X.It
- XEntries can be added before another entry.
- X.It
- XThey may be traversed backwards, from tail to head.
- X.El
- XHowever:
- X.Bl -enum -compact -offset indent
- X.It
- XAll list insertions and removals must specify the head of the list.
- X.It
- XEach head entry requires two pointers rather than one.
- X.It
- XThe termination condition for traversal is more complex.
- X.It
- XCode size is about 40% greater and operations run about 45% slower
- Xthan lists.
- X.El
- X.Pp
- XIn the macro definitions,
- X.Fa TYPE
- Xis the name of a user defined structure,
- Xthat must contain a field of type
- X.Li LIST_ENTRY ,
- X.Li TAILQ_ENTRY ,
- Xor
- X.Li CIRCLEQ_ENTRY ,
- Xnamed
- X.Fa NAME .
- XThe argument
- X.Fa HEADNAME
- Xis the name of a user defined structure that must be declared
- Xusing the macros
- X.Li LIST_HEAD ,
- X.Li TAILQ_HEAD ,
- Xor
- X.Li CIRCLEQ_HEAD .
- XSee the examples below for further explanation of how these
- Xmacros are used.
- X.Sh LISTS
- XA list is headed by a structure defined by the
- X.Nm LIST_HEAD
- Xmacro.
- XThis structure contains a single pointer to the first element
- Xon the list.
- XThe elements are doubly linked so that an arbitrary element can be
- Xremoved without traversing the list.
- XNew elements can be added to the list after an existing element or
- Xat the head of the list.
- XA
- X.Fa LIST_HEAD
- Xstructure is declared as follows:
- X.Bd -literal -offset indent
- XLIST_HEAD(HEADNAME, TYPE) head;
- X.Ed
- X.sp
- Xwhere
- X.Fa HEADNAME
- Xis the name of the structure to be defined, and
- X.Fa TYPE
- Xis the type of the elements to be linked into the list.
- XA pointer to the head of the list can later be declared as:
- X.Bd -literal -offset indent
- Xstruct HEADNAME *headp;
- X.Ed
- X.sp
- X(The names
- X.Li head
- Xand
- X.Li headp
- Xare user selectable.)
- X.Pp
- XThe macro
- X.Nm LIST_ENTRY
- Xdeclares a structure that connects the elements in
- Xthe list.
- X.Pp
- XThe macro
- X.Nm LIST_INIT
- Xinitializes the list referenced by
- X.Fa head .
- X.Pp
- XThe macro
- X.Nm LIST_INSERT_HEAD
- Xinserts the new element
- X.Fa elm
- Xat the head of the list.
- X.Pp
- XThe macro
- X.Nm LIST_INSERT_AFTER
- Xinserts the new element
- X.Fa elm
- Xafter the element
- X.Fa listelm .
- X.Pp
- XThe macro
- X.Nm LIST_REMOVE
- Xremoves the element
- X.Fa elm
- Xfrom the list.
- X.Sh LIST EXAMPLE
- X.Bd -literal
- XLIST_HEAD(listhead, entry) head;
- Xstruct listhead *headp; /* List head. */
- Xstruct entry {
- X ...
- X LIST_ENTRY(entry) entries; /* List. */
- X ...
- X} *n1, *n2, *np;
- X
- XLIST_INIT(&head); /* Initialize the list. */
- X
- Xn1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- XLIST_INSERT_HEAD(&head, n1, entries);
- X
- Xn2 = malloc(sizeof(struct entry)); /* Insert after. */
- XLIST_INSERT_AFTER(n1, n2, entries);
- X /* Forward traversal. */
- Xfor (np = head.lh_first; np != NULL; np = np->entries.le_next)
- X np-> ...
- X
- Xwhile (head.lh_first != NULL) /* Delete. */
- X LIST_REMOVE(head.lh_first, entries);
- X.Ed
- X.Sh TAIL QUEUES
- XA tail queue is headed by a structure defined by the
- X.Nm TAILQ_HEAD
- Xmacro.
- XThis structure contains a pair of pointers,
- Xone to the first element in the tail queue and the other to
- Xthe last element in the tail queue.
- XThe elements are doubly linked so that an arbitrary element can be
- Xremoved without traversing the tail queue.
- XNew elements can be added to the tail queue after an existing element,
- Xat the head of the tail queue, or at the end of the tail queue.
- XA
- X.Fa TAILQ_HEAD
- Xstructure is declared as follows:
- X.Bd -literal -offset indent
- XTAILQ_HEAD(HEADNAME, TYPE) head;
- X.Ed
- X.sp
- Xwhere
- X.Li HEADNAME
- Xis the name of the structure to be defined, and
- X.Li TYPE
- Xis the type of the elements to be linked into the tail queue.
- XA pointer to the head of the tail queue can later be declared as:
- X.Bd -literal -offset indent
- Xstruct HEADNAME *headp;
- X.Ed
- X.sp
- X(The names
- X.Li head
- Xand
- X.Li headp
- Xare user selectable.)
- X.Pp
- XThe macro
- X.Nm TAILQ_ENTRY
- Xdeclares a structure that connects the elements in
- Xthe tail queue.
- X.Pp
- XThe macro
- X.Nm TAILQ_INIT
- Xinitializes the tail queue referenced by
- X.Fa head .
- X.Pp
- XThe macro
- X.Nm TAILQ_INSERT_HEAD
- Xinserts the new element
- X.Fa elm
- Xat the head of the tail queue.
- X.Pp
- XThe macro
- X.Nm TAILQ_INSERT_TAIL
- Xinserts the new element
- X.Fa elm
- Xat the end of the tail queue.
- X.Pp
- XThe macro
- X.Nm TAILQ_INSERT_AFTER
- Xinserts the new element
- X.Fa elm
- Xafter the element
- X.Fa listelm .
- X.Pp
- XThe macro
- X.Nm TAILQ_REMOVE
- Xremoves the element
- X.Fa elm
- Xfrom the tail queue.
- X.Sh TAIL QUEUE EXAMPLE
- X.Bd -literal
- XTAILQ_HEAD(tailhead, entry) head;
- Xstruct tailhead *headp; /* Tail queue head. */
- Xstruct entry {
- X ...
- X TAILQ_ENTRY(entry) entries; /* Tail queue. */
- X ...
- X} *n1, *n2, *np;
- X
- XTAILQ_INIT(&head); /* Initialize the queue. */
- X
- Xn1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- XTAILQ_INSERT_HEAD(&head, n1, entries);
- X
- Xn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
- XTAILQ_INSERT_TAIL(&head, n1, entries);
- X
- Xn2 = malloc(sizeof(struct entry)); /* Insert after. */
- XTAILQ_INSERT_AFTER(&head, n1, n2, entries);
- X /* Forward traversal. */
- Xfor (np = head.tqh_first; np != NULL; np = np->entries.tqe_next)
- X np-> ...
- X /* Delete. */
- Xwhile (head.tqh_first != NULL)
- X TAILQ_REMOVE(&head, head.tqh_first, entries);
- X.Ed
- X.Sh CIRCULAR QUEUES
- XA circular queue is headed by a structure defined by the
- X.Nm CIRCLEQ_HEAD
- Xmacro.
- XThis structure contains a pair of pointers,
- Xone to the first element in the circular queue and the other to the
- Xlast element in the circular queue.
- XThe elements are doubly linked so that an arbitrary element can be
- Xremoved without traversing the queue.
- XNew elements can be added to the queue after an existing element,
- Xbefore an existing element, at the head of the queue, or at the end
- Xof the queue.
- XA
- X.Fa CIRCLEQ_HEAD
- Xstructure is declared as follows:
- X.Bd -literal -offset indent
- XCIRCLEQ_HEAD(HEADNAME, TYPE) head;
- X.Ed
- X.sp
- Xwhere
- X.Li HEADNAME
- Xis the name of the structure to be defined, and
- X.Li TYPE
- Xis the type of the elements to be linked into the circular queue.
- XA pointer to the head of the circular queue can later be declared as:
- X.Bd -literal -offset indent
- Xstruct HEADNAME *headp;
- X.Ed
- X.sp
- X(The names
- X.Li head
- Xand
- X.Li headp
- Xare user selectable.)
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_ENTRY
- Xdeclares a structure that connects the elements in
- Xthe circular queue.
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_INIT
- Xinitializes the circular queue referenced by
- X.Fa head .
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_INSERT_HEAD
- Xinserts the new element
- X.Fa elm
- Xat the head of the circular queue.
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_INSERT_TAIL
- Xinserts the new element
- X.Fa elm
- Xat the end of the circular queue.
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_INSERT_AFTER
- Xinserts the new element
- X.Fa elm
- Xafter the element
- X.Fa listelm .
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_INSERT_BEFORE
- Xinserts the new element
- X.Fa elm
- Xbefore the element
- X.Fa listelm .
- X.Pp
- XThe macro
- X.Nm CIRCLEQ_REMOVE
- Xremoves the element
- X.Fa elm
- Xfrom the circular queue.
- X.Sh CIRCULAR QUEUE EXAMPLE
- X.Bd -literal
- XCIRCLEQ_HEAD(circleq, entry) head;
- Xstruct circleq *headp; /* Circular queue head. */
- Xstruct entry {
- X ...
- X CIRCLEQ_ENTRY entries; /* Circular queue. */
- X ...
- X} *n1, *n2, *np;
- X
- XCIRCLEQ_INIT(&head); /* Initialize the circular queue. */
- X
- Xn1 = malloc(sizeof(struct entry)); /* Insert at the head. */
- XCIRCLEQ_INSERT_HEAD(&head, n1, entries);
- X
- Xn1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
- XCIRCLEQ_INSERT_TAIL(&head, n1, entries);
- X
- Xn2 = malloc(sizeof(struct entry)); /* Insert after. */
- XCIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
- X
- Xn2 = malloc(sizeof(struct entry)); /* Insert before. */
- XCIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
- X /* Forward traversal. */
- Xfor (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next)
- X np-> ...
- X /* Reverse traversal. */
- Xfor (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev)
- X np-> ...
- X /* Delete. */
- Xwhile (head.cqh_first != (void *)&head)
- X CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
- X.Ed
- X.Sh HISTORY
- XThe
- X.Nm queue
- Xfunctions first appeared in 4.4BSD.
- END-of-queue.3
- echo x - queue.h
- sed 's/^X//' >queue.h << 'END-of-queue.h'
- X/*
- X * Copyright (c) 1991, 1993
- X * The Regents of the University of California. All rights reserved.
- X *
- X * Redistribution and use in source and binary forms, with or without
- X * modification, are permitted provided that the following conditions
- X * are met:
- X * 1. Redistributions of source code must retain the above copyright
- X * notice, this list of conditions and the following disclaimer.
- X * 2. Redistributions in binary form must reproduce the above copyright
- X * notice, this list of conditions and the following disclaimer in the
- X * documentation and/or other materials provided with the distribution.
- X * 3. All advertising materials mentioning features or use of this software
- X * must display the following acknowledgement:
- X * This product includes software developed by the University of
- X * California, Berkeley and its contributors.
- X * 4. Neither the name of the University nor the names of its contributors
- X * may be used to endorse or promote products derived from this software
- X * without specific prior written permission.
- X *
- X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- X * SUCH DAMAGE.
- X *
- X * @(#)queue.h 8.3 (Berkeley) 12/13/93
- X */
- X
- X#ifndef _QUEUE_H_
- X#define _QUEUE_H_
- X
- X/*
- X * This file defines three types of data structures: lists, tail queues,
- X * and circular queues.
- X *
- X * A list is headed by a single forward pointer (or an array of forward
- X * pointers for a hash table header). The elements are doubly linked
- X * so that an arbitrary element can be removed without a need to
- X * traverse the list. New elements can be added to the list after
- X * an existing element or at the head of the list. A list may only be
- X * traversed in the forward direction.
- X *
- X * A tail queue is headed by a pair of pointers, one to the head of the
- X * list and the other to the tail of the list. The elements are doubly
- X * linked so that an arbitrary element can be removed without a need to
- X * traverse the list. New elements can be added to the list after
- X * an existing element, at the head of the list, or at the end of the
- X * list. A tail queue may only be traversed in the forward direction.
- X *
- X * A circle queue is headed by a pair of pointers, one to the head of the
- X * list and the other to the tail of the list. The elements are doubly
- X * linked so that an arbitrary element can be removed without a need to
- X * traverse the list. New elements can be added to the list before or after
- X * an existing element, at the head of the list, or at the end of the list.
- X * A circle queue may be traversed in either direction, but has a more
- X * complex end of list detection.
- X *
- X * For details on the use of these macros, see the queue(3) manual page.
- X */
- X
- X/*
- X * List definitions.
- X */
- X#define LIST_HEAD(name, type) \
- Xstruct name { \
- X struct type *lh_first; /* first element */ \
- X}
- X
- X#define LIST_ENTRY(type) \
- Xstruct { \
- X struct type *le_next; /* next element */ \
- X struct type **le_prev; /* address of previous next element */ \
- X}
- X
- X/*
- X * List functions.
- X */
- X#define LIST_INIT(head) { \
- X (head)->lh_first = NULL; \
- X}
- X
- X#define LIST_INSERT_AFTER(listelm, elm, field) { \
- X if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
- X (listelm)->field.le_next->field.le_prev = \
- X &(elm)->field.le_next; \
- X (listelm)->field.le_next = (elm); \
- X (elm)->field.le_prev = &(listelm)->field.le_next; \
- X}
- X
- X#define LIST_INSERT_HEAD(head, elm, field) { \
- X if (((elm)->field.le_next = (head)->lh_first) != NULL) \
- X (head)->lh_first->field.le_prev = &(elm)->field.le_next;\
- X (head)->lh_first = (elm); \
- X (elm)->field.le_prev = &(head)->lh_first; \
- X}
- X
- X#define LIST_REMOVE(elm, field) { \
- X if ((elm)->field.le_next != NULL) \
- X (elm)->field.le_next->field.le_prev = \
- X (elm)->field.le_prev; \
- X *(elm)->field.le_prev = (elm)->field.le_next; \
- X}
- X
- X/*
- X * Tail queue definitions.
- X */
- X#define TAILQ_HEAD(name, type) \
- Xstruct name { \
- X struct type *tqh_first; /* first element */ \
- X struct type **tqh_last; /* addr of last next element */ \
- X}
- X
- X#define TAILQ_ENTRY(type) \
- Xstruct { \
- X struct type *tqe_next; /* next element */ \
- X struct type **tqe_prev; /* address of previous next element */ \
- X}
- X
- X/*
- X * Tail queue functions.
- X */
- X#define TAILQ_INIT(head) { \
- X (head)->tqh_first = NULL; \
- X (head)->tqh_last = &(head)->tqh_first; \
- X}
- X
- X#define TAILQ_INSERT_HEAD(head, elm, field) { \
- X if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
- X (elm)->field.tqe_next->field.tqe_prev = \
- X &(elm)->field.tqe_next; \
- X else \
- X (head)->tqh_last = &(elm)->field.tqe_next; \
- X (head)->tqh_first = (elm); \
- X (elm)->field.tqe_prev = &(head)->tqh_first; \
- X}
- X
- X#define TAILQ_INSERT_TAIL(head, elm, field) { \
- X (elm)->field.tqe_next = NULL; \
- X (elm)->field.tqe_prev = (head)->tqh_last; \
- X *(head)->tqh_last = (elm); \
- X (head)->tqh_last = &(elm)->field.tqe_next; \
- X}
- X
- X#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \
- X if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
- X (elm)->field.tqe_next->field.tqe_prev = \
- X &(elm)->field.tqe_next; \
- X else \
- X (head)->tqh_last = &(elm)->field.tqe_next; \
- X (listelm)->field.tqe_next = (elm); \
- X (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
- X}
- X
- X#define TAILQ_REMOVE(head, elm, field) { \
- X if (((elm)->field.tqe_next) != NULL) \
- X (elm)->field.tqe_next->field.tqe_prev = \
- X (elm)->field.tqe_prev; \
- X else \
- X (head)->tqh_last = (elm)->field.tqe_prev; \
- X *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
- X}
- X
- X/*
- X * Circular queue definitions.
- X */
- X#define CIRCLEQ_HEAD(name, type) \
- Xstruct name { \
- X struct type *cqh_first; /* first element */ \
- X struct type *cqh_last; /* last element */ \
- X}
- X
- X#define CIRCLEQ_ENTRY(type) \
- Xstruct { \
- X struct type *cqe_next; /* next element */ \
- X struct type *cqe_prev; /* previous element */ \
- X}
- X
- X/*
- X * Circular queue functions.
- X */
- X#define CIRCLEQ_INIT(head) { \
- X (head)->cqh_first = (void *)(head); \
- X (head)->cqh_last = (void *)(head); \
- X}
- X
- X#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \
- X (elm)->field.cqe_next = (listelm)->field.cqe_next; \
- X (elm)->field.cqe_prev = (listelm); \
- X if ((listelm)->field.cqe_next == (void *)(head)) \
- X (head)->cqh_last = (elm); \
- X else \
- X (listelm)->field.cqe_next->field.cqe_prev = (elm); \
- X (listelm)->field.cqe_next = (elm); \
- X}
- X
- X#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \
- X (elm)->field.cqe_next = (listelm); \
- X (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- X if ((listelm)->field.cqe_prev == (void *)(head)) \
- X (head)->cqh_first = (elm); \
- X else \
- X (listelm)->field.cqe_prev->field.cqe_next = (elm); \
- X (listelm)->field.cqe_prev = (elm); \
- X}
- X
- X#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \
- X (elm)->field.cqe_next = (head)->cqh_first; \
- X (elm)->field.cqe_prev = (void *)(head); \
- X if ((head)->cqh_last == (void *)(head)) \
- X (head)->cqh_last = (elm); \
- X else \
- X (head)->cqh_first->field.cqe_prev = (elm); \
- X (head)->cqh_first = (elm); \
- X}
- X
- X#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \
- X (elm)->field.cqe_next = (void *)(head); \
- X (elm)->field.cqe_prev = (head)->cqh_last; \
- X if ((head)->cqh_first == (void *)(head)) \
- X (head)->cqh_first = (elm); \
- X else \
- X (head)->cqh_last->field.cqe_next = (elm); \
- X (head)->cqh_last = (elm); \
- X}
- X
- X#define CIRCLEQ_REMOVE(head, elm, field) { \
- X if ((elm)->field.cqe_next == (void *)(head)) \
- X (head)->cqh_last = (elm)->field.cqe_prev; \
- X else \
- X (elm)->field.cqe_next->field.cqe_prev = \
- X (elm)->field.cqe_prev; \
- X if ((elm)->field.cqe_prev == (void *)(head)) \
- X (head)->cqh_first = (elm)->field.cqe_next; \
- X else \
- X (elm)->field.cqe_prev->field.cqe_next = \
- X (elm)->field.cqe_next; \
- X}
- X#endif /* !_QUEUE_H_ */
- END-of-queue.h
- exit
-
-