queue(3)
NAME
SLIST_EMPTY, SLIST_ENTRY, SLIST_FIRST, SLIST_FOREACH,
SLIST_FOREACH_SAFE
SLIST_HEAD, SLIST_HEAD_INITIALIZER, SLIST_INIT,
SLIST_INSERT_AFTER
SLIST_INSERT_HEAD, SLIST_NEXT, SLIST_REMOVE_HEAD,
SLIST_REMOVE
STAILQ_CONCAT, STAILQ_EMPTY, STAILQ_ENTRY, STAILQ_FIRST,
STAILQ_FOREACH
STAILQ_FOREACH_SAFE, STAILQ_HEAD, STAILQ_HEAD_INITIALIZER,
STAILQ_INIT
STAILQ_INSERT_AFTER, STAILQ_INSERT_HEAD, STAILQ_INSERT_TAIL,
STAILQ_LAST
STAILQ_NEXT, STAILQ_REMOVE_HEAD, STAILQ_REMOVE, LIST_EMPTY,
LIST_ENTRY
LIST_FIRST, LIST_FOREACH, LIST_FOREACH_SAFE, LIST_HEAD, LIST_HEAD_INITIALIZER, LIST_INIT, LIST_INSERT_AFTER,
LIST_INSERT_BEFORE
LIST_INSERT_HEAD, LIST_NEXT, LIST_REMOVE, TAILQ_CONCAT,
TAILQ_EMPTY
TAILQ_ENTRY, TAILQ_FIRST, TAILQ_FOREACH, TAILQ_FOREACH_SAFE, TAILQ_FOREACH_REVERSE, TAILQ_FOREACH_REVERSE_SAFE,
TAILQ_HEAD
TAILQ_HEAD_INITIALIZER, TAILQ_INIT, TAILQ_INSERT_AFTER, TAILQ_INSERT_BEFORE, TAILQ_INSERT_HEAD, TAILQ_INSERT_TAIL,
TAILQ_LAST
- TAILQ_NEXT, TAILQ_PREV, TAILQ_REMOVE - implementations of
- singly-linked lists, singly-linked tail queues, lists and tail queues
SYNOPSIS
#include <sys/queue.h> SLIST_EMPTY(SLIST_HEAD *head); SLIST_ENTRY(TYPE); SLIST_FIRST(SLIST_HEAD *head); SLIST_FOREACH(TYPE *var, SLIST_HEAD *head, SLIST_ENTRY NAME); SLIST_FOREACH_SAFE(TYPE *var, SLIST_HEAD *head, SLIST_ENTRY NAME, TYPE *temp_var); SLIST_HEAD(HEADNAME, TYPE); SLIST_HEAD_INITIALIZER(SLIST_HEAD head); SLIST_INIT(SLIST_HEAD *head); SLIST_INSERT_AFTER(TYPE *listelm, TYPE *elm, SLIST_ENTRY NAME); SLIST_INSERT_HEAD(SLIST_HEAD *head, TYPE *elm, SLIST_ENTRY NAME); SLIST_NEXT(TYPE *elm, SLIST_ENTRY NAME); SLIST_REMOVE_HEAD(SLIST_HEAD *head, SLIST_ENTRY NAME); SLIST_REMOVE(SLIST_HEAD *head, TYPE *elm, TYPE, SLIST_ENTRY NAME); STAILQ_CONCAT(STAILQ_HEAD *head1, STAILQ_HEAD *head2); STAILQ_EMPTY(STAILQ_HEAD *head); STAILQ_ENTRY(TYPE); STAILQ_FIRST(STAILQ_HEAD *head); STAILQ_FOREACH(TYPE *var, STAILQ_HEAD *head, STAILQ_ENTRY NAME); STAILQ_FOREACH_SAFE(TYPE *var, STAILQ_HEAD *head, STAILQ_ENTRY NAME, TYPE *temp_var); STAILQ_HEAD(HEADNAME, TYPE); STAILQ_HEAD_INITIALIZER(STAILQ_HEAD head); STAILQ_INIT(STAILQ_HEAD *head); STAILQ_INSERT_AFTER(STAILQ_HEAD *head, TYPE *listelm, TYPE *elm, STAILQ_ENTRY NAME); STAILQ_INSERT_HEAD(STAILQ_HEAD *head, TYPE *elm, STAILQ_ENTRY NAME); STAILQ_INSERT_TAIL(STAILQ_HEAD *head, TYPE *elm, STAILQ_ENTRY NAME); STAILQ_LAST(STAILQ_HEAD *head, TYPE, STAILQ_ENTRY NAME); STAILQ_NEXT(TYPE *elm, STAILQ_ENTRY NAME); STAILQ_REMOVE_HEAD(STAILQ_HEAD *head, STAILQ_ENTRY NAME); STAILQ_REMOVE(STAILQ_HEAD *head, TYPE *elm, TYPE, STAILQ_ENTRY NAME); LIST_EMPTY(LIST_HEAD *head); LIST_ENTRY(TYPE); LIST_FIRST(LIST_HEAD *head); LIST_FOREACH(TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME); LIST_FOREACH_SAFE(TYPE *var, LIST_HEAD *head, LIST_ENTRY NAME, TYPE *temp_var); LIST_HEAD(HEADNAME, TYPE); LIST_HEAD_INITIALIZER(LIST_HEAD head); LIST_INIT(LIST_HEAD *head); LIST_INSERT_AFTER(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME); LIST_INSERT_BEFORE(TYPE *listelm, TYPE *elm, LIST_ENTRY NAME); LIST_INSERT_HEAD(LIST_HEAD *head, TYPE *elm, LIST_ENTRY NAME); LIST_NEXT(TYPE *elm, LIST_ENTRY NAME); LIST_REMOVE(TYPE *elm, LIST_ENTRY NAME); TAILQ_CONCAT(TAILQ_HEAD *head1, TAILQ_HEAD *head2, TAILQ_ENTRY NAME); TAILQ_EMPTY(TAILQ_HEAD *head); TAILQ_ENTRY(TYPE); TAILQ_FIRST(TAILQ_HEAD *head); TAILQ_FOREACH(TYPE *var, TAILQ_HEAD *head, TAILQ_ENTRY NAME); TAILQ_FOREACH_SAFE(TYPE *var, TAILQ_HEAD *head, TAILQ_ENTRY NAME, TYPE *temp_var); TAILQ_FOREACH_REVERSE(TYPE *var, TAILQ_HEAD *head, HEADNAME, TAILQ_ENTRY NAME); TAILQ_FOREACH_REVERSE_SAFE(TYPE *var, TAILQ_HEAD *head, HEADNAME, TAILQ_ENTRY NAME, TYPE *temp_var); TAILQ_HEAD(HEADNAME, TYPE); TAILQ_HEAD_INITIALIZER(TAILQ_HEAD head); TAILQ_INIT(TAILQ_HEAD *head); TAILQ_INSERT_AFTER(TAILQ_HEAD *head, TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME); TAILQ_INSERT_BEFORE(TYPE *listelm, TYPE *elm, TAILQ_ENTRY NAME); TAILQ_INSERT_HEAD(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME); TAILQ_INSERT_TAIL(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME); TAILQ_LAST(TAILQ_HEAD *head, HEADNAME); TAILQ_NEXT(TYPE *elm, TAILQ_ENTRY NAME); TAILQ_PREV(TYPE *elm, HEADNAME, TAILQ_ENTRY NAME); TAILQ_REMOVE(TAILQ_HEAD *head, TYPE *elm, TAILQ_ENTRY NAME);
DESCRIPTION
- These macros define and operate on four types of data struc
- tures: singlylinked lists, singly-linked tail queues, lists, and tail
- queues. All four structures support the following 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. O(1) removal of an entry from the head of the
- list. 4. O(n) removal of any entry in the list. 5. Forward traversal through the list.
- Singly-linked lists are the simplest of the four data struc
- tures and support only the above functionality. Singly-linked lists are
- ideal for applications with large datasets and few or no removals, or
- for implementing a LIFO queue.
- Singly-linked tail queues add the following functionality: 1. Entries can be added at the end of a list. 2. They may be concatenated.
- However: 1. All list insertions must specify the head of the
- list. 2. Each head entry requires two pointers rather than
- one. 3. Code size is about 15% greater and operations run
- about 20% slower than singly-linked lists.
- Singly-linked tailqs are ideal for applications with large
- datasets and few or no removals, or for implementing a FIFO queue.
- All doubly linked types of data structures (lists and tail
- queues) additionally allow: 1. Insertion of a new entry before any element in
- the list. 2. O(1) removal of any entry in the list.
- However: 1. Each elements requires two pointers rather than
- one. 2. Code size and execution time of operations (ex
- cept for removal) is about twice that of the singly-linked
- data-structures.
- Linked lists are the simplest of the doubly linked data
- structures and support only the above functionality over singly-linked
- lists.
- Tail queues add the following functionality: 1. Entries can be added at the end of a list. 2. They may be traversed backwards, from tail to
- head. 3. They may be concatenated.
- However: 1. All list insertions and removals must specify the
- head of the list.
- 2. Each head entry requires two pointers rather than
- one. 3. Code size is about 15% greater and operations run
- about 20% slower than singly-linked lists.
- In the macro definitions, TYPE is the name of a user defined
- structure, that must contain a field of type SLIST_ENTRY, STAILQ_ENTRY,
- LIST_ENTRY, or TAILQ_ENTRY, named NAME. The argument HEADNAME is the
- name of a user defined structure that must be declared using the macros
- SLIST_HEAD, STAILQ_HEAD, LIST_HEAD, or TAILQ_HEAD. See the examples be
- low for further explanation of how these macros are used.
SINGLY-LINKED LISTS
A singly-linked list is headed by a structure defined by the
SLIST_HEAD
- macro. This structure contains a single pointer to the
- first element on the list. The elements are singly linked for minimum space
- and pointer manipulation overhead at the expense of O(n) removal for ar
- bitrary elements. New elements can be added to the list after an ex
- isting element or at the head of the list. An SLIST_HEAD structure is de
- clared as follows:
- SLIST_HEAD(HEADNAME, TYPE) head;
- where HEADNAME is the name of the structure to be defined,
- and TYPE is the type of the elements to be linked into the list. A
- pointer to the head of the list can later be declared as:
- struct HEADNAME *headp;
- (The names head and headp are user selectable.)
- The macro SLIST_HEAD_INITIALIZER evaluates to an initializer
- for the list head.
- The macro SLIST_EMPTY evaluates to true if there are no ele
- ments in the list.
- The macro SLIST_ENTRY declares a structure that connects the
- elements in the list.
- The macro SLIST_FIRST returns the first element in the list
- or NULL if the list is empty.
- The macro SLIST_FOREACH traverses the list referenced by
- head in the forward direction, assigning each element in turn to var.
- The macro SLIST_FOREACH_SAFE traverses the list referenced
- by head in the forward direction, assigning each element in turn to var.
- However, unlike SLIST_FOREACH() here it is permitted to both remove
- var as well as free it from within the loop safely without interfering with
- the traversal.
- The macro SLIST_INIT initializes the list referenced by
- head.
- The macro SLIST_INSERT_HEAD inserts the new element elm at
- the head of the list.
- The macro SLIST_INSERT_AFTER inserts the new element elm af
- ter the element listelm.
- The macro SLIST_NEXT returns the next element in the list.
- The macro SLIST_REMOVE_HEAD removes the element elm from the
- head of the list. For optimum efficiency, elements being removed from
- the head of the list should explicitly use this macro instead of the
- generic SLIST_REMOVE macro.
- The macro SLIST_REMOVE removes the element elm from the
- list.
SINGLY-LINKED LIST EXAMPLE
- SLIST_HEAD(slisthead, entry) head =
- SLIST_HEAD_INITIALIZER(head);
- struct slisthead *headp; /* Singly-linked
- List head. */ struct entry { ... SLIST_ENTRY(entry) entries; /* Singly-linked
- List. */ ...
- } *n1, *n2, *n3, *np;
- SLIST_INIT(&head); /* Initialize the
- list. */
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- head. */ SLIST_INSERT_HEAD(&head, n1, entries);
- n2 = malloc(sizeof(struct entry)); /* Insert after. */ SLIST_INSERT_AFTER(n1, n2, entries);
- SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */ free(n2);
- n3 = SLIST_FIRST(&head); SLIST_REMOVE_HEAD(&head, entries); /* Deletion from the
- head. */ free(n3);/* Forward traver
- sal. */
- SLIST_FOREACH(np, &head, entries) np-> ... /* Safe forward
- traversal. */
- SLIST_FOREACH_SAFE(np, &head, entries, np_temp) { np->do_stuff(); ... SLIST_REMOVE(&head, np, entry, entries); free(np);
- }
- while (!SLIST_EMPTY(&head)) { /* List Deletion. */ n1 = SLIST_FIRST(&head); SLIST_REMOVE_HEAD(&head, entries); free(n1);
- }
SINGLY-LINKED TAIL QUEUES
- A singly-linked tail queue is headed by a structure defined
- by the STAILQ_HEAD macro. This structure contains a pair of point
- ers, one to the first element in the tail queue and the other to the
- last element in the tail queue. The elements are singly linked for minimum
- space and pointer manipulation overhead at the expense of O(n) removal
- for arbitrary elements. New elements can be added to the tail queue
- after an existing element, at the head of the tail queue, or at the
- end of the tail queue. A STAILQ_HEAD structure is declared as follows:
- STAILQ_HEAD(HEADNAME, TYPE) head;
- where HEADNAME is the name of the structure to be defined,
- and TYPE is the type of the elements to be linked into the tail queue.
- A pointer to the head of the tail queue can later be declared as:
- struct HEADNAME *headp;
- (The names head and headp are user selectable.)
- The macro STAILQ_HEAD_INITIALIZER evaluates to an initializ
- er for the tail queue head.
- The macro STAILQ_CONCAT concatenates the tail queue headed
- by head2 onto the end of the one headed by head1 removing all entries from
- the former.
- The macro STAILQ_EMPTY evaluates to true if there are no
- items on the tail queue.
- The macro STAILQ_ENTRY declares a structure that connects
- the elements in the tail queue.
- The macro STAILQ_FIRST returns the first item on the tail
- queue or NULL if the tail queue is empty.
- The macro STAILQ_FOREACH traverses the tail queue referenced
- by head in the forward direction, assigning each element in turn to
- var.
- The macro STAILQ_FOREACH_SAFE traverses the tail queue ref
- erenced by head in the forward direction, assigning each element in turn to
- var. However, unlike STAILQ_FOREACH() here it is permitted to both
- remove var as well as free it from within the loop safely without inter
- fering with the traversal.
- The macro STAILQ_INIT initializes the tail queue referenced
- by head.
- The macro STAILQ_INSERT_HEAD inserts the new element elm at
- the head of the tail queue.
- The macro STAILQ_INSERT_TAIL inserts the new element elm at
- the end of the tail queue.
- The macro STAILQ_INSERT_AFTER inserts the new element elm
- after the element listelm.
- The macro STAILQ_LAST returns the last item on the tail
- queue. If the tail queue is empty the return value is undefined.
- The macro STAILQ_NEXT returns the next item on the tail
- queue, or NULL this item is the last.
- The macro STAILQ_REMOVE_HEAD removes the element at the head
- of the tail queue. For optimum efficiency, elements being removed from
- the head of the tail queue should use this macro explicitly rather than
- the generic STAILQ_REMOVE macro.
- The macro STAILQ_REMOVE removes the element elm from the
- tail queue.
SINGLY-LINKED TAIL QUEUE EXAMPLE
- STAILQ_HEAD(stailhead, entry) head =
- STAILQ_HEAD_INITIALIZER(head);
- struct stailhead *headp; /* Singly-linked
- tail queue head. */ struct entry { ... STAILQ_ENTRY(entry) entries; /* Tail queue. */ ...
- } *n1, *n2, *n3, *np;
- STAILQ_INIT(&head); /* Initialize the
- queue. */
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- head. */ STAILQ_INSERT_HEAD(&head, n1, entries);
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- tail. */ STAILQ_INSERT_TAIL(&head, n1, entries);
- n2 = malloc(sizeof(struct entry)); /* Insert after. */ STAILQ_INSERT_AFTER(&head, n1, n2, entries); /* Deletion. */
- STAILQ_REMOVE(&head, n2, entry, entries); free(n2); /* Deletion from the
- head. */
- n3 = STAILQ_FIRST(&head); STAILQ_REMOVE_HEAD(&head, entries); free(n3);/* Forward traver
- sal. */
- STAILQ_FOREACH(np, &head, entries) np-> ... /* Safe forward
- traversal. */
- STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) { np->do_stuff(); ... STAILQ_REMOVE(&head, np, entry, entries); free(np);
- } /* TailQ Deletion.
- */
- while (!STAILQ_EMPTY(&head)) { n1 = STAILQ_FIRST(&head); STAILQ_REMOVE_HEAD(&head, entries); free(n1);
- } /* Faster TailQ
- Deletion. */
- n1 = STAILQ_FIRST(&head); while (n1 != NULL) { n2 = STAILQ_NEXT(n1, entries); free(n1); n1 = n2;
- } STAILQ_INIT(&head);
LISTS
- A list is headed by a structure defined by the LIST_HEAD
- macro. This structure contains a single pointer to the first element on
- the list. The elements are doubly linked so that an arbitrary element
- can be removed without traversing the list. New elements can be
- added to the list after an existing element, before an existing element,
- or at the head of the list. A LIST_HEAD structure is declared as fol
- lows:
- LIST_HEAD(HEADNAME, TYPE) head;
- where HEADNAME is the name of the structure to be defined,
- and TYPE is the type of the elements to be linked into the list. A
- pointer to the head of the list can later be declared as:
- struct HEADNAME *headp;
- (The names head and headp are user selectable.)
- The macro LIST_HEAD_INITIALIZER evaluates to an initializer
- for the list head.
- The macro LIST_EMPTY evaluates to true if there are no ele
- ments in the list.
- The macro LIST_ENTRY declares a structure that connects the
- elements in the list.
- The macro LIST_FIRST returns the first element in the list
- or NULL if the list is empty.
- The macro LIST_FOREACH traverses the list referenced by head
- in the forward direction, assigning each element in turn to var.
- The macro LIST_FOREACH_SAFE traverses the list referenced by
- head in the forward direction, assigning each element in turn to var.
- However, unlike LIST_FOREACH() here it is permitted to both remove
- var as well as free it from within the loop safely without interfering with
- the traversal.
- The macro LIST_INIT initializes the list referenced by head.
- The macro LIST_INSERT_HEAD inserts the new element elm at
- the head of the list.
- The macro LIST_INSERT_AFTER inserts the new element elm af
- ter the element listelm.
- The macro LIST_INSERT_BEFORE inserts the new element elm be
- fore the element listelm.
- The macro LIST_NEXT returns the next element in the list, or
- NULL if this is the last.
- The macro LIST_REMOVE removes the element elm from the list.
LIST EXAMPLE
- LIST_HEAD(listhead, entry) head =
- LIST_HEAD_INITIALIZER(head);
- struct listhead *headp; /* List head. */ struct entry { ... LIST_ENTRY(entry) entries; /* List. */ ...
- } *n1, *n2, *n3, *np, *np_temp;
- LIST_INIT(&head); /* Initialize the
- list. */
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- head. */ LIST_INSERT_HEAD(&head, n1, entries);
- n2 = malloc(sizeof(struct entry)); /* Insert after. */ LIST_INSERT_AFTER(n1, n2, entries);
- n3 = malloc(sizeof(struct entry)); /* Insert before. */ LIST_INSERT_BEFORE(n2, n3, entries);
- LIST_REMOVE(n2, entries); /* Deletion. */ free(n2);/* Forward traver
- sal. */
- LIST_FOREACH(np, &head, entries) np-> ...
- /* Safe forward
- traversal. */
- LIST_FOREACH_SAFE(np, &head, entries, np_temp) { np->do_stuff(); ... LIST_REMOVE(np, entries); free(np);
- }
- while (!LIST_EMPTY(&head)) { /* List Deletion. */ n1 = LIST_FIRST(&head); LIST_REMOVE(n1, entries); free(n1);
- }
- n1 = LIST_FIRST(&head); /* Faster List Dele
- tion. */ while (n1 != NULL) { n2 = LIST_NEXT(n1, entries); free(n1); n1 = n2;
- } LIST_INIT(&head);
TAIL QUEUES
A tail queue is headed by a structure defined by the
TAILQ_HEAD
- This structure contains a pair of pointers, one to the first
- element in the tail queue and the other to the last element in the tail
- queue. The elements are doubly linked so that an arbitrary element can
- be removed without traversing the tail queue. New elements can be
- added to the tail queue after an existing element, before an existing element,
- at the head of the tail queue, or at the end of the tail queue. A
- TAILQ_HEAD structure is declared as follows:
- TAILQ_HEAD(HEADNAME, TYPE) head;
- where HEADNAME is the name of the structure to be defined,
- and TYPE is the type of the elements to be linked into the tail queue.
- A pointer to the head of the tail queue can later be declared as:
- struct HEADNAME *headp;
- (The names head and headp are user selectable.)
- The macro TAILQ_HEAD_INITIALIZER evaluates to an initializer
- for the tail queue head.
- The macro TAILQ_CONCAT concatenates the tail queue headed by
- head2 onto the end of the one headed by head1 removing all entries from
- the former.
- The macro TAILQ_EMPTY evaluates to true if there are no
- items on the tail queue.
- The macro TAILQ_ENTRY declares a structure that connects the
- elements in the tail queue.
- The macro TAILQ_FIRST returns the first item on the tail
- queue or NULL if the tail queue is empty.
- The macro TAILQ_FOREACH traverses the tail queue referenced
- by head in the forward direction, assigning each element in turn to
- var. var is set to NULL if the loop completes normally, or if there were no
- elements.
- The macro TAILQ_FOREACH_REVERSE traverses the tail queue
- referenced by head in the reverse direction, assigning each element in
- turn to var.
- The macros TAILQ_FOREACH_SAFE and TAILQ_FOREACH_REVERSE_SAFE
- traverse the list referenced by head in the forward or reverse direction
- respectively, assigning each element in turn to var. However, unlike
- their unsafe counterparts, TAILQ_FOREACH and TAILQ_FOREACH_REVERSE permit
- to both remove var as well as free it from within the loop safely
- without interfering with the traversal.
- The macro TAILQ_INIT initializes the tail queue referenced
- by head.
- The macro TAILQ_INSERT_HEAD inserts the new element elm at
- the head of the tail queue.
- The macro TAILQ_INSERT_TAIL inserts the new element elm at
- the end of the tail queue.
- The macro TAILQ_INSERT_AFTER inserts the new element elm af
- ter the element listelm.
- The macro TAILQ_INSERT_BEFORE inserts the new element elm
- before the element listelm.
- The macro TAILQ_LAST returns the last item on the tail
- queue. If the tail queue is empty the return value is undefined.
- The macro TAILQ_NEXT returns the next item on the tail
- queue, or NULL if this item is the last.
- The macro TAILQ_PREV returns the previous item on the tail
- queue, or NULL if this item is the first.
- The macro TAILQ_REMOVE removes the element elm from the tail
- queue.
TAIL QUEUE EXAMPLE
- TAILQ_HEAD(tailhead, entry) head =
- TAILQ_HEAD_INITIALIZER(head);
- struct tailhead *headp; /* Tail queue head.
- */ struct entry { ... TAILQ_ENTRY(entry) entries; /* Tail queue. */ ...
- } *n1, *n2, *n3, *np;
- TAILQ_INIT(&head); /* Initialize the
- queue. */
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- head. */ TAILQ_INSERT_HEAD(&head, n1, entries);
- n1 = malloc(sizeof(struct entry)); /* Insert at the
- tail. */ TAILQ_INSERT_TAIL(&head, n1, entries);
- n2 = malloc(sizeof(struct entry)); /* Insert after. */ TAILQ_INSERT_AFTER(&head, n1, n2, entries);
- n3 = malloc(sizeof(struct entry)); /* Insert before. */ TAILQ_INSERT_BEFORE(n2, n3, entries);
- TAILQ_REMOVE(&head, n2, entries); /* Deletion. */ free(n2);/* Forward traver
- sal. */
- TAILQ_FOREACH(np, &head, entries) np-> ... /* Safe forward
- traversal. */
- TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) { np->do_stuff(); ... TAILQ_REMOVE(&head, np, entries); free(np);
- }/* Reverse traver
- sal. */
- TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries) np-> ... /* TailQ Deletion.
- */
- while (!TAILQ_EMPTY(&head)) { n1 = TAILQ_FIRST(&head); TAILQ_REMOVE(&head, n1, entries); free(n1);
- } /* Faster TailQ
- Deletion. */
- n1 = TAILQ_FIRST(&head); while (n1 != NULL) { n2 = TAILQ_NEXT(n1, entries); free(n1); n1 = n2;
- } TAILQ_INIT(&head);
HISTORY
- The queue functions first appeared in 4.4BSD.
- BSD January 24, 1994