Blame man3/queue.3

Packit 7cfc04
.\" Copyright (c) 1993
Packit 7cfc04
.\"	The Regents of the University of California.  All rights reserved.
Packit 7cfc04
.\"
Packit 7cfc04
.\" %%%LICENSE_START(BSD_3_CLAUSE_UCB)
Packit 7cfc04
.\" Redistribution and use in source and binary forms, with or without
Packit 7cfc04
.\" modification, are permitted provided that the following conditions
Packit 7cfc04
.\" are met:
Packit 7cfc04
.\" 1. Redistributions of source code must retain the above copyright
Packit 7cfc04
.\"    notice, this list of conditions and the following disclaimer.
Packit 7cfc04
.\" 2. Redistributions in binary form must reproduce the above copyright
Packit 7cfc04
.\"    notice, this list of conditions and the following disclaimer in the
Packit 7cfc04
.\"    documentation and/or other materials provided with the distribution.
Packit 7cfc04
.\" 3. Neither the name of the University nor the names of its contributors
Packit 7cfc04
.\"    may be used to endorse or promote products derived from this software
Packit 7cfc04
.\"    without specific prior written permission.
Packit 7cfc04
.\"
Packit 7cfc04
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit 7cfc04
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 7cfc04
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit 7cfc04
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit 7cfc04
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 7cfc04
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit 7cfc04
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit 7cfc04
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit 7cfc04
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit 7cfc04
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit 7cfc04
.\" SUCH DAMAGE.
Packit 7cfc04
.\" %%%LICENSE_END
Packit 7cfc04
.\"
Packit 7cfc04
.\"	@(#)queue.3	8.2 (Berkeley) 1/24/94
Packit 7cfc04
.\" $FreeBSD$
Packit 7cfc04
.\"
Packit 7cfc04
.Dd February 7, 2015
Packit 7cfc04
.Dt QUEUE 3
Packit 7cfc04
.Os
Packit 7cfc04
.Sh NAME
Packit 7cfc04
.Nm SLIST_EMPTY ,
Packit 7cfc04
.Nm SLIST_ENTRY ,
Packit 7cfc04
.Nm SLIST_FIRST ,
Packit 7cfc04
.Nm SLIST_FOREACH ,
Packit 7cfc04
.\" .Nm SLIST_FOREACH_FROM ,
Packit 7cfc04
.\" .Nm SLIST_FOREACH_SAFE ,
Packit 7cfc04
.\" .Nm SLIST_FOREACH_FROM_SAFE ,
Packit 7cfc04
.Nm SLIST_HEAD ,
Packit 7cfc04
.Nm SLIST_HEAD_INITIALIZER ,
Packit 7cfc04
.Nm SLIST_INIT ,
Packit 7cfc04
.Nm SLIST_INSERT_AFTER ,
Packit 7cfc04
.Nm SLIST_INSERT_HEAD ,
Packit 7cfc04
.Nm SLIST_NEXT ,
Packit 7cfc04
.\" .Nm SLIST_REMOVE_AFTER ,
Packit 7cfc04
.Nm SLIST_REMOVE_HEAD ,
Packit 7cfc04
.Nm SLIST_REMOVE ,
Packit 7cfc04
.\" .Nm SLIST_SWAP ,
Packit 7cfc04
.Nm STAILQ_CONCAT ,
Packit 7cfc04
.Nm STAILQ_EMPTY ,
Packit 7cfc04
.Nm STAILQ_ENTRY ,
Packit 7cfc04
.Nm STAILQ_FIRST ,
Packit 7cfc04
.Nm STAILQ_FOREACH ,
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_FROM ,
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_SAFE ,
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_FROM_SAFE ,
Packit 7cfc04
.Nm STAILQ_HEAD ,
Packit 7cfc04
.Nm STAILQ_HEAD_INITIALIZER ,
Packit 7cfc04
.Nm STAILQ_INIT ,
Packit 7cfc04
.Nm STAILQ_INSERT_AFTER ,
Packit 7cfc04
.Nm STAILQ_INSERT_HEAD ,
Packit 7cfc04
.Nm STAILQ_INSERT_TAIL ,
Packit 7cfc04
.\" .Nm STAILQ_LAST ,
Packit 7cfc04
.Nm STAILQ_NEXT ,
Packit 7cfc04
.\" .Nm STAILQ_REMOVE_AFTER ,
Packit 7cfc04
.Nm STAILQ_REMOVE_HEAD ,
Packit 7cfc04
.Nm STAILQ_REMOVE ,
Packit 7cfc04
.\" .Nm STAILQ_SWAP ,
Packit 7cfc04
.Nm LIST_EMPTY ,
Packit 7cfc04
.Nm LIST_ENTRY ,
Packit 7cfc04
.Nm LIST_FIRST ,
Packit 7cfc04
.Nm LIST_FOREACH ,
Packit 7cfc04
.\" .Nm LIST_FOREACH_FROM ,
Packit 7cfc04
.\" .Nm LIST_FOREACH_SAFE ,
Packit 7cfc04
.\" .Nm LIST_FOREACH_FROM_SAFE ,
Packit 7cfc04
.Nm LIST_HEAD ,
Packit 7cfc04
.Nm LIST_HEAD_INITIALIZER ,
Packit 7cfc04
.Nm LIST_INIT ,
Packit 7cfc04
.Nm LIST_INSERT_AFTER ,
Packit 7cfc04
.Nm LIST_INSERT_BEFORE ,
Packit 7cfc04
.Nm LIST_INSERT_HEAD ,
Packit 7cfc04
.Nm LIST_NEXT ,
Packit 7cfc04
.\" .Nm LIST_PREV ,
Packit 7cfc04
.Nm LIST_REMOVE ,
Packit 7cfc04
.\" .Nm LIST_SWAP ,
Packit 7cfc04
.Nm TAILQ_CONCAT ,
Packit 7cfc04
.Nm TAILQ_EMPTY ,
Packit 7cfc04
.Nm TAILQ_ENTRY ,
Packit 7cfc04
.Nm TAILQ_FIRST ,
Packit 7cfc04
.Nm TAILQ_FOREACH ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_FROM ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_SAFE ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_FROM_SAFE ,
Packit 7cfc04
.Nm TAILQ_FOREACH_REVERSE ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_FROM ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_SAFE ,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_FROM_SAFE ,
Packit 7cfc04
.Nm TAILQ_HEAD ,
Packit 7cfc04
.Nm TAILQ_HEAD_INITIALIZER ,
Packit 7cfc04
.Nm TAILQ_INIT ,
Packit 7cfc04
.Nm TAILQ_INSERT_AFTER ,
Packit 7cfc04
.Nm TAILQ_INSERT_BEFORE ,
Packit 7cfc04
.Nm TAILQ_INSERT_HEAD ,
Packit 7cfc04
.Nm TAILQ_INSERT_TAIL ,
Packit 7cfc04
.Nm TAILQ_LAST ,
Packit 7cfc04
.Nm TAILQ_NEXT ,
Packit 7cfc04
.Nm TAILQ_PREV ,
Packit 7cfc04
.Nm TAILQ_REMOVE ,
Packit 7cfc04
.Nm TAILQ_SWAP
Packit 7cfc04
.Nd implementations of singly-linked lists, singly-linked tail queues,
Packit 7cfc04
lists and tail queues
Packit 7cfc04
.Sh SYNOPSIS
Packit 7cfc04
.In sys/queue.h
Packit 7cfc04
.\"
Packit 7cfc04
.Fn SLIST_EMPTY "SLIST_HEAD *head"
Packit 7cfc04
.Fn SLIST_ENTRY "TYPE"
Packit 7cfc04
.Fn SLIST_FIRST "SLIST_HEAD *head"
Packit 7cfc04
.Fn SLIST_FOREACH "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn SLIST_FOREACH_FROM "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn SLIST_FOREACH_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.\" .Fn SLIST_FOREACH_FROM_SAFE "TYPE *var" "SLIST_HEAD *head" "SLIST_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.Fn SLIST_HEAD "HEADNAME" "TYPE"
Packit 7cfc04
.Fn SLIST_HEAD_INITIALIZER "SLIST_HEAD head"
Packit 7cfc04
.Fn SLIST_INIT "SLIST_HEAD *head"
Packit 7cfc04
.Fn SLIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "SLIST_ENTRY NAME"
Packit 7cfc04
.Fn SLIST_INSERT_HEAD "SLIST_HEAD *head" "TYPE *elm" "SLIST_ENTRY NAME"
Packit 7cfc04
.Fn SLIST_NEXT "TYPE *elm" "SLIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME"
Packit 7cfc04
.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
Packit 7cfc04
.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "SLIST_ENTRY NAME"
Packit 7cfc04
.\"
Packit 7cfc04
.Fn STAILQ_CONCAT "STAILQ_HEAD *head1" "STAILQ_HEAD *head2"
Packit 7cfc04
.Fn STAILQ_EMPTY "STAILQ_HEAD *head"
Packit 7cfc04
.Fn STAILQ_ENTRY "TYPE"
Packit 7cfc04
.Fn STAILQ_FIRST "STAILQ_HEAD *head"
Packit 7cfc04
.Fn STAILQ_FOREACH "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn STAILQ_FOREACH_FROM "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn STAILQ_FOREACH_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.\" .Fn STAILQ_FOREACH_FROM_SAFE "TYPE *var" "STAILQ_HEAD *head" "STAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.Fn STAILQ_HEAD "HEADNAME" "TYPE"
Packit 7cfc04
.Fn STAILQ_HEAD_INITIALIZER "STAILQ_HEAD head"
Packit 7cfc04
.Fn STAILQ_INIT "STAILQ_HEAD *head"
Packit 7cfc04
.Fn STAILQ_INSERT_AFTER "STAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "STAILQ_ENTRY NAME"
Packit 7cfc04
.Fn STAILQ_INSERT_HEAD "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
Packit 7cfc04
.Fn STAILQ_INSERT_TAIL "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn STAILQ_LAST "STAILQ_HEAD *head" "TYPE" "STAILQ_ENTRY NAME"
Packit 7cfc04
.Fn STAILQ_NEXT "TYPE *elm" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
Packit 7cfc04
.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
Packit 7cfc04
.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "STAILQ_ENTRY NAME"
Packit 7cfc04
.\"
Packit 7cfc04
.Fn LIST_EMPTY "LIST_HEAD *head"
Packit 7cfc04
.Fn LIST_ENTRY "TYPE"
Packit 7cfc04
.Fn LIST_FIRST "LIST_HEAD *head"
Packit 7cfc04
.Fn LIST_FOREACH "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn LIST_FOREACH_FROM "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn LIST_FOREACH_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.\" .Fn LIST_FOREACH_FROM_SAFE "TYPE *var" "LIST_HEAD *head" "LIST_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.Fn LIST_HEAD "HEADNAME" "TYPE"
Packit 7cfc04
.Fn LIST_HEAD_INITIALIZER "LIST_HEAD head"
Packit 7cfc04
.Fn LIST_INIT "LIST_HEAD *head"
Packit 7cfc04
.Fn LIST_INSERT_AFTER "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
Packit 7cfc04
.Fn LIST_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "LIST_ENTRY NAME"
Packit 7cfc04
.Fn LIST_INSERT_HEAD "LIST_HEAD *head" "TYPE *elm" "LIST_ENTRY NAME"
Packit 7cfc04
.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
Packit 7cfc04
.\" .Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
Packit 7cfc04
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
Packit 7cfc04
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
Packit 7cfc04
.\"
Packit 7cfc04
.Fn TAILQ_CONCAT "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_EMPTY "TAILQ_HEAD *head"
Packit 7cfc04
.Fn TAILQ_ENTRY "TYPE"
Packit 7cfc04
.Fn TAILQ_FIRST "TAILQ_HEAD *head"
Packit 7cfc04
.Fn TAILQ_FOREACH "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_FROM "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "TAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.Fn TAILQ_FOREACH_REVERSE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_REVERSE_FROM "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_REVERSE_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.\" .Fn TAILQ_FOREACH_REVERSE_FROM_SAFE "TYPE *var" "TAILQ_HEAD *head" "HEADNAME" "TAILQ_ENTRY NAME" "TYPE *temp_var"
Packit 7cfc04
.Fn TAILQ_HEAD "HEADNAME" "TYPE"
Packit 7cfc04
.Fn TAILQ_HEAD_INITIALIZER "TAILQ_HEAD head"
Packit 7cfc04
.Fn TAILQ_INIT "TAILQ_HEAD *head"
Packit 7cfc04
.Fn TAILQ_INSERT_AFTER "TAILQ_HEAD *head" "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_INSERT_BEFORE "TYPE *listelm" "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_INSERT_HEAD "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_INSERT_TAIL "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_LAST "TAILQ_HEAD *head" "HEADNAME"
Packit 7cfc04
.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
Packit 7cfc04
.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
Packit 7cfc04
.\"
Packit 7cfc04
.Sh DESCRIPTION
Packit 7cfc04
These macros define and operate on four types of data structures:
Packit 7cfc04
singly-linked lists, singly-linked tail queues, lists, and tail queues.
Packit 7cfc04
All four structures support the following functionality:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
Insertion of a new entry at the head of the list.
Packit 7cfc04
.It
Packit 7cfc04
Insertion of a new entry after any element in the list.
Packit 7cfc04
.It
Packit 7cfc04
O(1) removal of an entry from the head of the list.
Packit 7cfc04
.It
Packit 7cfc04
Forward traversal through the list.
Packit 7cfc04
.It
Packit 7cfc04
Swapping the contents of two lists.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
Singly-linked lists are the simplest of the four data structures
Packit 7cfc04
and support only the above functionality.
Packit 7cfc04
Singly-linked lists are ideal for applications with large datasets
Packit 7cfc04
and few or no removals,
Packit 7cfc04
or for implementing a LIFO queue.
Packit 7cfc04
Singly-linked lists add the following functionality:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
O(n) removal of any entry in the list.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
Singly-linked tail queues add the following functionality:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
Entries can be added at the end of a list.
Packit 7cfc04
.It
Packit 7cfc04
O(n) removal of any entry in the list.
Packit 7cfc04
.It
Packit 7cfc04
They may be concatenated.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
However:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
All list insertions must specify the head of the list.
Packit 7cfc04
.It
Packit 7cfc04
Each head entry requires two pointers rather than one.
Packit 7cfc04
.It
Packit 7cfc04
Code size is about 15% greater and operations run about 20% slower
Packit 7cfc04
than singly-linked lists.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
Singly-linked tail queues are ideal for applications with large datasets and
Packit 7cfc04
few or no removals,
Packit 7cfc04
or for implementing a FIFO queue.
Packit 7cfc04
.Pp
Packit 7cfc04
All doubly linked types of data structures (lists and tail queues)
Packit 7cfc04
additionally allow:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
Insertion of a new entry before any element in the list.
Packit 7cfc04
.It
Packit 7cfc04
O(1) removal of any entry in the list.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
However:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
Each element requires two pointers rather than one.
Packit 7cfc04
.It
Packit 7cfc04
Code size and execution time of operations (except for removal) is about
Packit 7cfc04
twice that of the singly-linked data-structures.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
Linked lists are the simplest of the doubly linked data structures.
Packit 7cfc04
They add the following functionality over the above:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
They may be traversed backwards.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
However:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
To traverse backwards, an entry to begin the traversal and the list in
Packit 7cfc04
which it is contained must be specified.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
Tail queues add the following functionality:
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
Entries can be added at the end of a list.
Packit 7cfc04
.It
Packit 7cfc04
They may be traversed backwards, from tail to head.
Packit 7cfc04
.It
Packit 7cfc04
They may be concatenated.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
However:
Packit 7cfc04
.Pp
Packit 7cfc04
.Bl -enum -compact -offset indent
Packit 7cfc04
.It
Packit 7cfc04
All list insertions and removals must specify the head of the list.
Packit 7cfc04
.It
Packit 7cfc04
Each head entry requires two pointers rather than one.
Packit 7cfc04
.It
Packit 7cfc04
Code size is about 15% greater and operations run about 20% slower
Packit 7cfc04
than singly-linked lists.
Packit 7cfc04
.El
Packit 7cfc04
.Pp
Packit 7cfc04
In the macro definitions,
Packit 7cfc04
.Fa TYPE
Packit 7cfc04
is the name of a user defined structure,
Packit 7cfc04
that must contain a field of type
Packit 7cfc04
.Li SLIST_ENTRY ,
Packit 7cfc04
.Li STAILQ_ENTRY ,
Packit 7cfc04
.Li LIST_ENTRY ,
Packit 7cfc04
or
Packit 7cfc04
.Li TAILQ_ENTRY ,
Packit 7cfc04
named
Packit 7cfc04
.Fa NAME .
Packit 7cfc04
The argument
Packit 7cfc04
.Fa HEADNAME
Packit 7cfc04
is the name of a user defined structure that must be declared
Packit 7cfc04
using the macros
Packit 7cfc04
.Li SLIST_HEAD ,
Packit 7cfc04
.Li STAILQ_HEAD ,
Packit 7cfc04
.Li LIST_HEAD ,
Packit 7cfc04
or
Packit 7cfc04
.Li TAILQ_HEAD .
Packit 7cfc04
See the examples below for further explanation of how these
Packit 7cfc04
macros are used.
Packit 7cfc04
.Ss Singly-linked lists
Packit 7cfc04
A singly-linked list is headed by a structure defined by the
Packit 7cfc04
.Nm SLIST_HEAD
Packit 7cfc04
macro.
Packit 7cfc04
This structure contains a single pointer to the first element
Packit 7cfc04
on the list.
Packit 7cfc04
The elements are singly linked for minimum space and pointer manipulation
Packit 7cfc04
overhead at the expense of O(n) removal for arbitrary elements.
Packit 7cfc04
New elements can be added to the list after an existing element or
Packit 7cfc04
at the head of the list.
Packit 7cfc04
An
Packit 7cfc04
.Fa SLIST_HEAD
Packit 7cfc04
structure is declared as follows:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
SLIST_HEAD(HEADNAME, TYPE) head;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
where
Packit 7cfc04
.Fa HEADNAME
Packit 7cfc04
is the name of the structure to be defined, and
Packit 7cfc04
.Fa TYPE
Packit 7cfc04
is the type of the elements to be linked into the list.
Packit 7cfc04
A pointer to the head of the list can later be declared as:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
struct HEADNAME *headp;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
(The names
Packit 7cfc04
.Li head
Packit 7cfc04
and
Packit 7cfc04
.Li headp
Packit 7cfc04
are user selectable.)
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_HEAD_INITIALIZER
Packit 7cfc04
evaluates to an initializer for the list
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_EMPTY
Packit 7cfc04
evaluates to true if there are no elements in the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_ENTRY
Packit 7cfc04
declares a structure that connects the elements in
Packit 7cfc04
the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_FIRST
Packit 7cfc04
returns the first element in the list or NULL if the list is empty.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_FOREACH
Packit 7cfc04
traverses the list referenced by
Packit 7cfc04
.Fa head
Packit 7cfc04
in the forward direction, assigning each element in
Packit 7cfc04
turn to
Packit 7cfc04
.Fa var .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm SLIST_FOREACH_FROM
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm SLIST_FOREACH
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found SLIST element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the SLIST referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm SLIST_FOREACH_SAFE
Packit 7cfc04
.\" traverses the list referenced by
Packit 7cfc04
.\" .Fa head
Packit 7cfc04
.\" in the forward direction, assigning each element in
Packit 7cfc04
.\" turn to
Packit 7cfc04
.\" .Fa var .
Packit 7cfc04
.\" However, unlike
Packit 7cfc04
.\" .Fn SLIST_FOREACH
Packit 7cfc04
.\" here it is permitted to both remove
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as well as free it from within the loop safely without interfering with the
Packit 7cfc04
.\" traversal.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm SLIST_FOREACH_FROM_SAFE
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm SLIST_FOREACH_SAFE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found SLIST element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the SLIST referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_INIT
Packit 7cfc04
initializes the list referenced by
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_INSERT_HEAD
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the head of the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_INSERT_AFTER
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
after the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_NEXT
Packit 7cfc04
returns the next element in the list.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm SLIST_REMOVE_AFTER
Packit 7cfc04
.\" removes the element after
Packit 7cfc04
.\" .Fa elm
Packit 7cfc04
.\" from the list.
Packit 7cfc04
.\" Unlike
Packit 7cfc04
.\" .Fa SLIST_REMOVE ,
Packit 7cfc04
.\" this macro does not traverse the entire list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_REMOVE_HEAD
Packit 7cfc04
removes the element
Packit 7cfc04
.Fa elm
Packit 7cfc04
from the head of the list.
Packit 7cfc04
For optimum efficiency,
Packit 7cfc04
elements being removed from the head of the list should explicitly use
Packit 7cfc04
this macro instead of the generic
Packit 7cfc04
.Fa SLIST_REMOVE
Packit 7cfc04
macro.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm SLIST_REMOVE
Packit 7cfc04
removes the element
Packit 7cfc04
.Fa elm
Packit 7cfc04
from the list.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm SLIST_SWAP
Packit 7cfc04
.\" swaps the contents of
Packit 7cfc04
.\" .Fa head1
Packit 7cfc04
.\" and
Packit 7cfc04
.\" .Fa head2 .
Packit 7cfc04
.Ss Singly-linked list example
Packit 7cfc04
.Bd -literal
Packit 7cfc04
SLIST_HEAD(slisthead, entry) head =
Packit 7cfc04
    SLIST_HEAD_INITIALIZER(head);
Packit 7cfc04
struct slisthead *headp;		/* Singly-linked List
Packit 7cfc04
                                           head. */
Packit 7cfc04
struct entry {
Packit 7cfc04
	...
Packit 7cfc04
	SLIST_ENTRY(entry) entries;	/* Singly-linked List. */
Packit 7cfc04
	...
Packit 7cfc04
} *n1, *n2, *n3, *np;
Packit 7cfc04
Packit 7cfc04
SLIST_INIT(&head;;			/* Initialize the list. */
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
Packit 7cfc04
SLIST_INSERT_HEAD(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n2 = malloc(sizeof(struct entry));	/* Insert after. */
Packit 7cfc04
SLIST_INSERT_AFTER(n1, n2, entries);
Packit 7cfc04
Packit 7cfc04
SLIST_REMOVE(&head, n2, entry, entries);/* Deletion. */
Packit 7cfc04
free(n2);
Packit 7cfc04
Packit 7cfc04
n3 = SLIST_FIRST(&head;;
Packit 7cfc04
SLIST_REMOVE_HEAD(&head, entries);	/* Deletion from the head. */
Packit 7cfc04
free(n3);
Packit 7cfc04
					/* Forward traversal. */
Packit 7cfc04
SLIST_FOREACH(np, &head, entries)
Packit 7cfc04
	np\-> ...
Packit 7cfc04
.\"					/* Safe forward traversal. */
Packit 7cfc04
.\"SLIST_FOREACH_SAFE(np, &head, entries, np_temp) {
Packit 7cfc04
.\"	np\->do_stuff();
Packit 7cfc04
.\"	...
Packit 7cfc04
.\"	SLIST_REMOVE(&head, np, entry, entries);
Packit 7cfc04
.\"	free(np);
Packit 7cfc04
.\"}
Packit 7cfc04
Packit 7cfc04
while (!SLIST_EMPTY(&head)) {		/* List Deletion. */
Packit 7cfc04
	n1 = SLIST_FIRST(&head;;
Packit 7cfc04
	SLIST_REMOVE_HEAD(&head, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
}
Packit 7cfc04
.Ed
Packit 7cfc04
.Ss Singly-linked tail queues
Packit 7cfc04
A singly-linked tail queue is headed by a structure defined by the
Packit 7cfc04
.Nm STAILQ_HEAD
Packit 7cfc04
macro.
Packit 7cfc04
This structure contains a pair of pointers,
Packit 7cfc04
one to the first element in the tail queue and the other to
Packit 7cfc04
the last element in the tail queue.
Packit 7cfc04
The elements are singly linked for minimum space and pointer
Packit 7cfc04
manipulation overhead at the expense of O(n) removal for arbitrary
Packit 7cfc04
elements.
Packit 7cfc04
New elements can be added to the tail queue after an existing element,
Packit 7cfc04
at the head of the tail queue, or at the end of the tail queue.
Packit 7cfc04
A
Packit 7cfc04
.Fa STAILQ_HEAD
Packit 7cfc04
structure is declared as follows:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
STAILQ_HEAD(HEADNAME, TYPE) head;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
where
Packit 7cfc04
.Li HEADNAME
Packit 7cfc04
is the name of the structure to be defined, and
Packit 7cfc04
.Li TYPE
Packit 7cfc04
is the type of the elements to be linked into the tail queue.
Packit 7cfc04
A pointer to the head of the tail queue can later be declared as:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
struct HEADNAME *headp;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
(The names
Packit 7cfc04
.Li head
Packit 7cfc04
and
Packit 7cfc04
.Li headp
Packit 7cfc04
are user selectable.)
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_HEAD_INITIALIZER
Packit 7cfc04
evaluates to an initializer for the tail queue
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_CONCAT
Packit 7cfc04
concatenates the tail queue headed by
Packit 7cfc04
.Fa head2
Packit 7cfc04
onto the end of the one headed by
Packit 7cfc04
.Fa head1
Packit 7cfc04
removing all entries from the former.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_EMPTY
Packit 7cfc04
evaluates to true if there are no items on the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_ENTRY
Packit 7cfc04
declares a structure that connects the elements in
Packit 7cfc04
the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_FIRST
Packit 7cfc04
returns the first item on the tail queue or NULL if the tail queue
Packit 7cfc04
is empty.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_FOREACH
Packit 7cfc04
traverses the tail queue referenced by
Packit 7cfc04
.Fa head
Packit 7cfc04
in the forward direction, assigning each element
Packit 7cfc04
in turn to
Packit 7cfc04
.Fa var .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_FROM
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm STAILQ_FOREACH
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found STAILQ element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the STAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_SAFE
Packit 7cfc04
.\" traverses the tail queue referenced by
Packit 7cfc04
.\" .Fa head
Packit 7cfc04
.\" in the forward direction, assigning each element
Packit 7cfc04
.\" in turn to
Packit 7cfc04
.\" .Fa var .
Packit 7cfc04
.\" However, unlike
Packit 7cfc04
.\" .Fn STAILQ_FOREACH
Packit 7cfc04
.\" here it is permitted to both remove
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as well as free it from within the loop safely without interfering with the
Packit 7cfc04
.\" traversal.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_FROM_SAFE
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm STAILQ_FOREACH_SAFE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found STAILQ element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the STAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_INIT
Packit 7cfc04
initializes the tail queue referenced by
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_INSERT_HEAD
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the head of the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_INSERT_TAIL
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the end of the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_INSERT_AFTER
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
after the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_LAST
Packit 7cfc04
.\" returns the last item on the tail queue.
Packit 7cfc04
.\" If the tail queue is empty the return value is
Packit 7cfc04
.\" .Dv NULL .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_NEXT
Packit 7cfc04
returns the next item on the tail queue, or NULL this item is the last.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_REMOVE_AFTER
Packit 7cfc04
.\" removes the element after
Packit 7cfc04
.\" .Fa elm
Packit 7cfc04
.\" from the tail queue.
Packit 7cfc04
.\" Unlike
Packit 7cfc04
.\" .Fa STAILQ_REMOVE ,
Packit 7cfc04
.\" this macro does not traverse the entire tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_REMOVE_HEAD
Packit 7cfc04
removes the element at the head of the tail queue.
Packit 7cfc04
For optimum efficiency,
Packit 7cfc04
elements being removed from the head of the tail queue should
Packit 7cfc04
use this macro explicitly rather than the generic
Packit 7cfc04
.Fa STAILQ_REMOVE
Packit 7cfc04
macro.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm STAILQ_REMOVE
Packit 7cfc04
removes the element
Packit 7cfc04
.Fa elm
Packit 7cfc04
from the tail queue.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm STAILQ_SWAP
Packit 7cfc04
.\" swaps the contents of
Packit 7cfc04
.\" .Fa head1
Packit 7cfc04
.\" and
Packit 7cfc04
.\" .Fa head2 .
Packit 7cfc04
.Ss Singly-linked tail queue example
Packit 7cfc04
.Bd -literal
Packit 7cfc04
STAILQ_HEAD(stailhead, entry) head =
Packit 7cfc04
    STAILQ_HEAD_INITIALIZER(head);
Packit 7cfc04
struct stailhead *headp;		/* Singly-linked tail queue head. */
Packit 7cfc04
struct entry {
Packit 7cfc04
	...
Packit 7cfc04
	STAILQ_ENTRY(entry) entries;	/* Tail queue. */
Packit 7cfc04
	...
Packit 7cfc04
} *n1, *n2, *n3, *np;
Packit 7cfc04
Packit 7cfc04
STAILQ_INIT(&head;;			/* Initialize the queue. */
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
Packit 7cfc04
STAILQ_INSERT_HEAD(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
Packit 7cfc04
STAILQ_INSERT_TAIL(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n2 = malloc(sizeof(struct entry));	/* Insert after. */
Packit 7cfc04
STAILQ_INSERT_AFTER(&head, n1, n2, entries);
Packit 7cfc04
					/* Deletion. */
Packit 7cfc04
STAILQ_REMOVE(&head, n2, entry, entries);
Packit 7cfc04
free(n2);
Packit 7cfc04
					/* Deletion from the head. */
Packit 7cfc04
n3 = STAILQ_FIRST(&head;;
Packit 7cfc04
STAILQ_REMOVE_HEAD(&head, entries);
Packit 7cfc04
free(n3);
Packit 7cfc04
					/* Forward traversal. */
Packit 7cfc04
STAILQ_FOREACH(np, &head, entries)
Packit 7cfc04
	np\-> ...
Packit 7cfc04
.\"					/* Safe forward traversal. */
Packit 7cfc04
.\"STAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
Packit 7cfc04
.\"	np\->do_stuff();
Packit 7cfc04
.\"	...
Packit 7cfc04
.\"	STAILQ_REMOVE(&head, np, entry, entries);
Packit 7cfc04
.\"	free(np);
Packit 7cfc04
.\"}
Packit 7cfc04
					/* TailQ Deletion. */
Packit 7cfc04
while (!STAILQ_EMPTY(&head)) {
Packit 7cfc04
	n1 = STAILQ_FIRST(&head;;
Packit 7cfc04
	STAILQ_REMOVE_HEAD(&head, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
}
Packit 7cfc04
					/* Faster TailQ Deletion. */
Packit 7cfc04
n1 = STAILQ_FIRST(&head;;
Packit 7cfc04
while (n1 != NULL) {
Packit 7cfc04
	n2 = STAILQ_NEXT(n1, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
	n1 = n2;
Packit 7cfc04
}
Packit 7cfc04
STAILQ_INIT(&head;;
Packit 7cfc04
.Ed
Packit 7cfc04
.Ss Lists
Packit 7cfc04
A list is headed by a structure defined by the
Packit 7cfc04
.Nm LIST_HEAD
Packit 7cfc04
macro.
Packit 7cfc04
This structure contains a single pointer to the first element
Packit 7cfc04
on the list.
Packit 7cfc04
The elements are doubly linked so that an arbitrary element can be
Packit 7cfc04
removed without traversing the list.
Packit 7cfc04
New elements can be added to the list after an existing element,
Packit 7cfc04
before an existing element, or at the head of the list.
Packit 7cfc04
A
Packit 7cfc04
.Fa LIST_HEAD
Packit 7cfc04
structure is declared as follows:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
LIST_HEAD(HEADNAME, TYPE) head;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
where
Packit 7cfc04
.Fa HEADNAME
Packit 7cfc04
is the name of the structure to be defined, and
Packit 7cfc04
.Fa TYPE
Packit 7cfc04
is the type of the elements to be linked into the list.
Packit 7cfc04
A pointer to the head of the list can later be declared as:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
struct HEADNAME *headp;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
(The names
Packit 7cfc04
.Li head
Packit 7cfc04
and
Packit 7cfc04
.Li headp
Packit 7cfc04
are user selectable.)
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_HEAD_INITIALIZER
Packit 7cfc04
evaluates to an initializer for the list
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_EMPTY
Packit 7cfc04
evaluates to true if there are no elements in the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_ENTRY
Packit 7cfc04
declares a structure that connects the elements in
Packit 7cfc04
the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_FIRST
Packit 7cfc04
returns the first element in the list or NULL if the list
Packit 7cfc04
is empty.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_FOREACH
Packit 7cfc04
traverses the list referenced by
Packit 7cfc04
.Fa head
Packit 7cfc04
in the forward direction, assigning each element in turn to
Packit 7cfc04
.Fa var .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm LIST_FOREACH_FROM
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm LIST_FOREACH
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found LIST element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the LIST referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm LIST_FOREACH_SAFE
Packit 7cfc04
.\" traverses the list referenced by
Packit 7cfc04
.\" .Fa head
Packit 7cfc04
.\" in the forward direction, assigning each element in turn to
Packit 7cfc04
.\" .Fa var .
Packit 7cfc04
.\" However, unlike
Packit 7cfc04
.\" .Fn LIST_FOREACH
Packit 7cfc04
.\" here it is permitted to both remove
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as well as free it from within the loop safely without interfering with the
Packit 7cfc04
.\" traversal.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm LIST_FOREACH_FROM_SAFE
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm LIST_FOREACH_SAFE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found LIST element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the LIST referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_INIT
Packit 7cfc04
initializes the list referenced by
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_INSERT_HEAD
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the head of the list.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_INSERT_AFTER
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
after the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_INSERT_BEFORE
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
before the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_NEXT
Packit 7cfc04
returns the next element in the list, or NULL if this is the last.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm LIST_PREV
Packit 7cfc04
.\" returns the previous element in the list, or NULL if this is the first.
Packit 7cfc04
.\" List
Packit 7cfc04
.\" .Fa head
Packit 7cfc04
.\" must contain element
Packit 7cfc04
.\" .Fa elm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm LIST_REMOVE
Packit 7cfc04
removes the element
Packit 7cfc04
.Fa elm
Packit 7cfc04
from the list.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm LIST_SWAP
Packit 7cfc04
.\" swaps the contents of
Packit 7cfc04
.\" .Fa head1
Packit 7cfc04
.\" and
Packit 7cfc04
.\" .Fa head2 .
Packit 7cfc04
.Ss List example
Packit 7cfc04
.Bd -literal
Packit 7cfc04
LIST_HEAD(listhead, entry) head =
Packit 7cfc04
    LIST_HEAD_INITIALIZER(head);
Packit 7cfc04
struct listhead *headp;			/* List head. */
Packit 7cfc04
struct entry {
Packit 7cfc04
	...
Packit 7cfc04
	LIST_ENTRY(entry) entries;	/* List. */
Packit 7cfc04
	...
Packit 7cfc04
} *n1, *n2, *n3, *np, *np_temp;
Packit 7cfc04
Packit 7cfc04
LIST_INIT(&head;;			/* Initialize the list. */
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
Packit 7cfc04
LIST_INSERT_HEAD(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n2 = malloc(sizeof(struct entry));	/* Insert after. */
Packit 7cfc04
LIST_INSERT_AFTER(n1, n2, entries);
Packit 7cfc04
Packit 7cfc04
n3 = malloc(sizeof(struct entry));	/* Insert before. */
Packit 7cfc04
LIST_INSERT_BEFORE(n2, n3, entries);
Packit 7cfc04
Packit 7cfc04
LIST_REMOVE(n2, entries);		/* Deletion. */
Packit 7cfc04
free(n2);
Packit 7cfc04
					/* Forward traversal. */
Packit 7cfc04
LIST_FOREACH(np, &head, entries)
Packit 7cfc04
	np\-> ...
Packit 7cfc04
Packit 7cfc04
.\" 					/* Safe forward traversal. */
Packit 7cfc04
.\" LIST_FOREACH_SAFE(np, &head, entries, np_temp) {
Packit 7cfc04
.\" 	np\->do_stuff();
Packit 7cfc04
.\" 	...
Packit 7cfc04
.\" 	LIST_REMOVE(np, entries);
Packit 7cfc04
.\" 	free(np);
Packit 7cfc04
.\" }
Packit 7cfc04
.\"
Packit 7cfc04
while (!LIST_EMPTY(&head)) {		/* List Deletion. */
Packit 7cfc04
	n1 = LIST_FIRST(&head;;
Packit 7cfc04
	LIST_REMOVE(n1, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
}
Packit 7cfc04
Packit 7cfc04
n1 = LIST_FIRST(&head;;			/* Faster List Deletion. */
Packit 7cfc04
while (n1 != NULL) {
Packit 7cfc04
	n2 = LIST_NEXT(n1, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
	n1 = n2;
Packit 7cfc04
}
Packit 7cfc04
LIST_INIT(&head;;
Packit 7cfc04
.Ed
Packit 7cfc04
.Ss Tail queues
Packit 7cfc04
A tail queue is headed by a structure defined by the
Packit 7cfc04
.Nm TAILQ_HEAD
Packit 7cfc04
macro.
Packit 7cfc04
This structure contains a pair of pointers,
Packit 7cfc04
one to the first element in the tail queue and the other to
Packit 7cfc04
the last element in the tail queue.
Packit 7cfc04
The elements are doubly linked so that an arbitrary element can be
Packit 7cfc04
removed without traversing the tail queue.
Packit 7cfc04
New elements can be added to the tail queue after an existing element,
Packit 7cfc04
before an existing element, at the head of the tail queue,
Packit 7cfc04
or at the end of the tail queue.
Packit 7cfc04
A
Packit 7cfc04
.Fa TAILQ_HEAD
Packit 7cfc04
structure is declared as follows:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
TAILQ_HEAD(HEADNAME, TYPE) head;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
where
Packit 7cfc04
.Li HEADNAME
Packit 7cfc04
is the name of the structure to be defined, and
Packit 7cfc04
.Li TYPE
Packit 7cfc04
is the type of the elements to be linked into the tail queue.
Packit 7cfc04
A pointer to the head of the tail queue can later be declared as:
Packit 7cfc04
.Bd -literal -offset indent
Packit 7cfc04
struct HEADNAME *headp;
Packit 7cfc04
.Ed
Packit 7cfc04
.Pp
Packit 7cfc04
(The names
Packit 7cfc04
.Li head
Packit 7cfc04
and
Packit 7cfc04
.Li headp
Packit 7cfc04
are user selectable.)
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_HEAD_INITIALIZER
Packit 7cfc04
evaluates to an initializer for the tail queue
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_CONCAT
Packit 7cfc04
concatenates the tail queue headed by
Packit 7cfc04
.Fa head2
Packit 7cfc04
onto the end of the one headed by
Packit 7cfc04
.Fa head1
Packit 7cfc04
removing all entries from the former.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_EMPTY
Packit 7cfc04
evaluates to true if there are no items on the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_ENTRY
Packit 7cfc04
declares a structure that connects the elements in
Packit 7cfc04
the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_FIRST
Packit 7cfc04
returns the first item on the tail queue or NULL if the tail queue
Packit 7cfc04
is empty.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_FOREACH
Packit 7cfc04
traverses the tail queue referenced by
Packit 7cfc04
.Fa head
Packit 7cfc04
in the forward direction, assigning each element in turn to
Packit 7cfc04
.Fa var .
Packit 7cfc04
.Fa var
Packit 7cfc04
is set to
Packit 7cfc04
.Dv NULL
Packit 7cfc04
if the loop completes normally, or if there were no elements.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_FROM
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm TAILQ_FOREACH
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found TAILQ element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the TAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_FOREACH_REVERSE
Packit 7cfc04
traverses the tail queue referenced by
Packit 7cfc04
.Fa head
Packit 7cfc04
in the reverse direction, assigning each element in turn to
Packit 7cfc04
.Fa var .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_FROM
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found TAILQ element and begins the reverse loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the last element in the TAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macros
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_SAFE
Packit 7cfc04
.\" and
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_SAFE
Packit 7cfc04
.\" traverse the list referenced by
Packit 7cfc04
.\" .Fa head
Packit 7cfc04
.\" in the forward or reverse direction respectively,
Packit 7cfc04
.\" assigning each element in turn to
Packit 7cfc04
.\" .Fa var .
Packit 7cfc04
.\" However, unlike their unsafe counterparts,
Packit 7cfc04
.\" .Nm TAILQ_FOREACH
Packit 7cfc04
.\" and
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE
Packit 7cfc04
.\" permit to both remove
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as well as free it from within the loop safely without interfering with the
Packit 7cfc04
.\" traversal.
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_FROM_SAFE
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_SAFE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found TAILQ element and begins the loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the first element in the TAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.\" .Pp
Packit 7cfc04
.\" The macro
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_FROM_SAFE
Packit 7cfc04
.\" behaves identically to
Packit 7cfc04
.\" .Nm TAILQ_FOREACH_REVERSE_SAFE
Packit 7cfc04
.\" when
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" is NULL, else it treats
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" as a previously found TAILQ element and begins the reverse loop at
Packit 7cfc04
.\" .Fa var
Packit 7cfc04
.\" instead of the last element in the TAILQ referenced by
Packit 7cfc04
.\" .Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_INIT
Packit 7cfc04
initializes the tail queue referenced by
Packit 7cfc04
.Fa head .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_INSERT_HEAD
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the head of the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_INSERT_TAIL
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
at the end of the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_INSERT_AFTER
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
after the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_INSERT_BEFORE
Packit 7cfc04
inserts the new element
Packit 7cfc04
.Fa elm
Packit 7cfc04
before the element
Packit 7cfc04
.Fa listelm .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_LAST
Packit 7cfc04
returns the last item on the tail queue.
Packit 7cfc04
If the tail queue is empty the return value is
Packit 7cfc04
.Dv NULL .
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_NEXT
Packit 7cfc04
returns the next item on the tail queue, or NULL if this item is the last.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_PREV
Packit 7cfc04
returns the previous item on the tail queue, or NULL if this item
Packit 7cfc04
is the first.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_REMOVE
Packit 7cfc04
removes the element
Packit 7cfc04
.Fa elm
Packit 7cfc04
from the tail queue.
Packit 7cfc04
.Pp
Packit 7cfc04
The macro
Packit 7cfc04
.Nm TAILQ_SWAP
Packit 7cfc04
swaps the contents of
Packit 7cfc04
.Fa head1
Packit 7cfc04
and
Packit 7cfc04
.Fa head2 .
Packit 7cfc04
.Ss Tail queue example
Packit 7cfc04
.Bd -literal
Packit 7cfc04
TAILQ_HEAD(tailhead, entry) head =
Packit 7cfc04
    TAILQ_HEAD_INITIALIZER(head);
Packit 7cfc04
struct tailhead *headp;			/* Tail queue head. */
Packit 7cfc04
struct entry {
Packit 7cfc04
	...
Packit 7cfc04
	TAILQ_ENTRY(entry) entries;	/* Tail queue. */
Packit 7cfc04
	...
Packit 7cfc04
} *n1, *n2, *n3, *np;
Packit 7cfc04
Packit 7cfc04
TAILQ_INIT(&head;;			/* Initialize the queue. */
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the head. */
Packit 7cfc04
TAILQ_INSERT_HEAD(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n1 = malloc(sizeof(struct entry));	/* Insert at the tail. */
Packit 7cfc04
TAILQ_INSERT_TAIL(&head, n1, entries);
Packit 7cfc04
Packit 7cfc04
n2 = malloc(sizeof(struct entry));	/* Insert after. */
Packit 7cfc04
TAILQ_INSERT_AFTER(&head, n1, n2, entries);
Packit 7cfc04
Packit 7cfc04
n3 = malloc(sizeof(struct entry));	/* Insert before. */
Packit 7cfc04
TAILQ_INSERT_BEFORE(n2, n3, entries);
Packit 7cfc04
Packit 7cfc04
TAILQ_REMOVE(&head, n2, entries);	/* Deletion. */
Packit 7cfc04
free(n2);
Packit 7cfc04
					/* Forward traversal. */
Packit 7cfc04
TAILQ_FOREACH(np, &head, entries)
Packit 7cfc04
	np\-> ...
Packit 7cfc04
.\" 					/* Safe forward traversal. */
Packit 7cfc04
.\" TAILQ_FOREACH_SAFE(np, &head, entries, np_temp) {
Packit 7cfc04
.\" 	np\->do_stuff();
Packit 7cfc04
.\" 	...
Packit 7cfc04
.\" 	TAILQ_REMOVE(&head, np, entries);
Packit 7cfc04
.\" 	free(np);
Packit 7cfc04
.\" }
Packit 7cfc04
					/* Reverse traversal. */
Packit 7cfc04
TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
Packit 7cfc04
	np\-> ...
Packit 7cfc04
					/* TailQ Deletion. */
Packit 7cfc04
while (!TAILQ_EMPTY(&head)) {
Packit 7cfc04
	n1 = TAILQ_FIRST(&head;;
Packit 7cfc04
	TAILQ_REMOVE(&head, n1, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
}
Packit 7cfc04
					/* Faster TailQ Deletion. */
Packit 7cfc04
n1 = TAILQ_FIRST(&head;;
Packit 7cfc04
while (n1 != NULL) {
Packit 7cfc04
	n2 = TAILQ_NEXT(n1, entries);
Packit 7cfc04
	free(n1);
Packit 7cfc04
	n1 = n2;
Packit 7cfc04
}
Packit 7cfc04
Packit 7cfc04
TAILQ_INIT(&head;;
Packit 7cfc04
n2 = malloc(sizeof(struct entry));  /* Insert before. */
Packit 7cfc04
CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
Packit 7cfc04
                                    /* Forward traversal. */
Packit 7cfc04
for (np = head.cqh_first; np != (void *)&head;
Packit 7cfc04
        np = np\->entries.cqe_next)
Packit 7cfc04
    np\-> ...
Packit 7cfc04
                                    /* Reverse traversal. */
Packit 7cfc04
for (np = head.cqh_last; np != (void *)&head; np = np\->entries.cqe_prev)
Packit 7cfc04
    np\-> ...
Packit 7cfc04
                                    /* Delete. */
Packit 7cfc04
while (head.cqh_first != (void *)&head)
Packit 7cfc04
    CIRCLEQ_REMOVE(&head, head.cqh_first, entries);
Packit 7cfc04
.Ed
Packit 7cfc04
.Sh CONFORMING TO
Packit 7cfc04
Not in POSIX.1, POSIX.1-2001 or POSIX.1-2008.
Packit 7cfc04
Present on the BSDs.
Packit 7cfc04
.Nm queue
Packit 7cfc04
functions first appeared in
Packit 7cfc04
.Bx 4.4 .
Packit 7cfc04
.Sh SEE ALSO
Packit 7cfc04
.Xr insque 3
Packit 7cfc04
.\" .Xr tree 3
Packit 7cfc04
.Sh COLOPHON
Packit 7cfc04
This page is part of release 4.15 of the Linux
Packit 7cfc04
.Em man-pages
Packit 7cfc04
project.
Packit 7cfc04
A description of the project,
Packit 7cfc04
information about reporting bugs,
Packit 7cfc04
and the latest version of this page,
Packit 7cfc04
can be found at
Packit 7cfc04
\%https://www.kernel.org/doc/man\-pages/.