Fn LIST_ENTRY TYPE Fn LIST_HEAD HEADNAME TYPE Fn LIST_INIT LIST_HEAD *head Fn LIST_INSERT_AFTER TYPE *listelm TYPE *elm LIST_ENTRY NAME Fn LIST_INSERT_BEFORE TYPE *listelm TYPE *elm LIST_ENTRY NAME Fn LIST_INSERT_HEAD LIST_HEAD *head TYPE *elm LIST_ENTRY NAME Fn LIST_REMOVE TYPE *elm LIST_ENTRY NAME
Fn TAILQ_ENTRY TYPE Fn TAILQ_HEAD HEADNAME TYPE Fn TAILQ_INIT TAILQ_HEAD *head Fn TAILQ_INSERT_AFTER TAILQ_HEAD *head TYPE *listelm TYPE *elm TAILQ_ENTRY NAME Fn TAILQ_INSERT_BEFORE TYPE *listelm TYPE *elm TAILQ_ENTRY NAME Fn TAILQ_INSERT_HEAD TAILQ_HEAD *head TYPE *elm TAILQ_ENTRY NAME Fn TAILQ_INSERT_TAIL TAILQ_HEAD *head TYPE *elm TAILQ_ENTRY NAME Fn TAILQ_REMOVE TAILQ_HEAD *head TYPE *elm TAILQ_ENTRY NAME
Fn CIRCLEQ_ENTRY TYPE Fn CIRCLEQ_HEAD HEADNAME TYPE Fn CIRCLEQ_INIT CIRCLEQ_HEAD *head Fn CIRCLEQ_INSERT_AFTER CIRCLEQ_HEAD *head TYPE *listelm TYPE *elm CIRCLEQ_ENTRY NAME Fn CIRCLEQ_INSERT_BEFORE CIRCLEQ_HEAD *head TYPE *listelm TYPE *elm CIRCLEQ_ENTRY NAME Fn CIRCLEQ_INSERT_HEAD CIRCLEQ_HEAD *head TYPE *elm CIRCLEQ_ENTRY NAME Fn CIRCLEQ_INSERT_TAIL CIRCLEQ_HEAD *head TYPE *elm CIRCLEQ_ENTRY NAME Fn CIRCLEQ_REMOVE CIRCLEQ_HEAD *head TYPE *elm CIRCLEQ_ENTRY NAME
Lists are the simplest of the three data structures and support only the above functionality.
Tail queues add the following functionality:
However:
Circular queues add the following functionality:
However:
In the macro definitions, Fa TYPE is the name of a user defined structure, that must contain a field of type LIST_ENTRY TAILQ_ENTRY or CIRCLEQ_ENTRY named Fa NAME . The argument Fa HEADNAME is the name of a user defined structure that must be declared using the macros LIST_HEAD TAILQ_HEAD or CIRCLEQ_HEAD See the examples below for further explanation of how these macros are used.
LIST_HEAD(HEADNAME, TYPE) head;
where Fa HEADNAME is the name of the structure to be defined, and Fa 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_ENTRY declares a structure that connects the elements in the list.
The macro LIST_INIT initializes the list referenced by Fa head .
The macro LIST_INSERT_HEAD inserts the new element Fa elm at the head of the list.
The macro LIST_INSERT_AFTER inserts the new element Fa elm after the element Fa listelm .
The macro LIST_INSERT_BEFORE inserts the new element Fa elm before the element Fa listelm .
The macro LIST_REMOVE removes the element Fa elm from the list.
LIST_HEAD(listhead, entry) head; struct listhead *headp; /* List head. */ struct entry { ... LIST_ENTRY(entry) entries; /* List. */ ... } *n1, *n2, *np; 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); n2 = malloc(sizeof(struct entry)); /* Insert before. */ LIST_INSERT_BEFORE(n1, n2, entries); /* Forward traversal. */ for (np = head.lh_first; np != NULL; np = np->entries.le_next) np-> ... while (head.lh_first != NULL) /* Delete. */ LIST_REMOVE(head.lh_first, entries);
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_ENTRY declares a structure that connects the elements in the tail queue.
The macro TAILQ_INIT initializes the tail queue referenced by Fa head .
The macro TAILQ_INSERT_HEAD inserts the new element Fa elm at the head of the tail queue.
The macro TAILQ_INSERT_TAIL inserts the new element Fa elm at the end of the tail queue.
The macro TAILQ_INSERT_AFTER inserts the new element Fa elm after the element Fa listelm .
The macro TAILQ_INSERT_BEFORE inserts the new element Fa elm before the element Fa listelm .
The macro TAILQ_REMOVE removes the element Fa elm from the tail queue.
TAILQ_HEAD(tailhead, entry) head; struct tailhead *headp; /* Tail queue head. */ struct entry { ... TAILQ_ENTRY(entry) entries; /* Tail queue. */ ... } *n1, *n2, *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); n2 = malloc(sizeof(struct entry)); /* Insert before. */ TAILQ_INSERT_BEFORE(n1, n2, entries); /* Forward traversal. */ for (np = head.tqh_first; np != NULL; np = np->entries.tqe_next) np-> ... /* Delete. */ while (head.tqh_first != NULL) TAILQ_REMOVE(&head, head.tqh_first, entries);
CIRCLEQ_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 circular queue. A pointer to the head of the circular queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The macro CIRCLEQ_ENTRY declares a structure that connects the elements in the circular queue.
The macro CIRCLEQ_INIT initializes the circular queue referenced by Fa head .
The macro CIRCLEQ_INSERT_HEAD inserts the new element Fa elm at the head of the circular queue.
The macro CIRCLEQ_INSERT_TAIL inserts the new element Fa elm at the end of the circular queue.
The macro CIRCLEQ_INSERT_AFTER inserts the new element Fa elm after the element Fa listelm .
The macro CIRCLEQ_INSERT_BEFORE inserts the new element Fa elm before the element Fa listelm .
The macro CIRCLEQ_REMOVE removes the element Fa elm from the circular queue.
CIRCLEQ_HEAD(circleq, entry) head; struct circleq *headp; /* Circular queue head. */ struct entry { ... CIRCLEQ_ENTRY entries; /* Circular queue. */ ... } *n1, *n2, *np; CIRCLEQ_INIT(&head); /* Initialize the circular queue. */ n1 = malloc(sizeof(struct entry)); /* Insert at the head. */ CIRCLEQ_INSERT_HEAD(&head, n1, entries); n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */ CIRCLEQ_INSERT_TAIL(&head, n1, entries); n2 = malloc(sizeof(struct entry)); /* Insert after. */ CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries); n2 = malloc(sizeof(struct entry)); /* Insert before. */ CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries); /* Forward traversal. */ for (np = head.cqh_first; np != (void *)&head; np = np->entries.cqe_next) np-> ... /* Reverse traversal. */ for (np = head.cqh_last; np != (void *)&head; np = np->entries.cqe_prev) np-> ... /* Delete. */ while (head.cqh_first != (void *)&head) CIRCLEQ_REMOVE(&head, head.cqh_first, entries);