On Mon, 8 Sep 2014, Jona Joachim wrote:
> On 2014-09-06, Gr?goire Duch?ne <[email protected]> wrote:
> > Hi,
> >
> > Although CIRCLEQ_* macros are deprecated, queue(3) does not say so.
>
> perhaps it would be interesting to mention why circle queues got
> deprecated.
Let's go a step further and remove them from the queue(3) manpage, leaving
just a blurb about why and recommending conversion to tail queues.
ok?
Philip
Index: queue.3
===================================================================
RCS file: /cvs/src/share/man/man3/queue.3,v
retrieving revision 1.59
diff -u -p -r1.59 queue.3
--- queue.3 14 Aug 2013 06:32:31 -0000 1.59
+++ queue.3 12 Sep 2014 19:46:19 -0000
@@ -98,27 +98,8 @@
.Nm TAILQ_INSERT_HEAD ,
.Nm TAILQ_INSERT_TAIL ,
.Nm TAILQ_REMOVE ,
-.Nm TAILQ_REPLACE ,
-.Nm CIRCLEQ_ENTRY ,
-.Nm CIRCLEQ_HEAD ,
-.Nm CIRCLEQ_HEAD_INITIALIZER ,
-.Nm CIRCLEQ_FIRST ,
-.Nm CIRCLEQ_LAST ,
-.Nm CIRCLEQ_END ,
-.Nm CIRCLEQ_NEXT ,
-.Nm CIRCLEQ_PREV ,
-.Nm CIRCLEQ_EMPTY ,
-.Nm CIRCLEQ_FOREACH ,
-.Nm CIRCLEQ_FOREACH_SAFE ,
-.Nm CIRCLEQ_FOREACH_REVERSE_SAFE ,
-.Nm CIRCLEQ_INIT ,
-.Nm CIRCLEQ_INSERT_AFTER ,
-.Nm CIRCLEQ_INSERT_BEFORE ,
-.Nm CIRCLEQ_INSERT_HEAD ,
-.Nm CIRCLEQ_INSERT_TAIL ,
-.Nm CIRCLEQ_REMOVE ,
-.Nm CIRCLEQ_REPLACE
-.Nd implementations of singly-linked lists, doubly-linked lists, simple
queues, tail queues, and circular queues
+.Nm TAILQ_REPLACE
+.Nd implementations of singly-linked lists, doubly-linked lists, simple
queues, and tail queues
.Sh SYNOPSIS
.In sys/queue.h
.Pp
@@ -233,44 +214,10 @@
.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
.Ft void
.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "struct TYPE *elm" "struct TYPE *elm2"
"FIELDNAME"
-.Pp
-.Fn CIRCLEQ_ENTRY "TYPE"
-.Fn CIRCLEQ_HEAD "HEADNAME" "TYPE"
-.Fn CIRCLEQ_HEAD_INITIALIZER "CIRCLEQ_HEAD head"
-.Ft "struct TYPE *"
-.Fn CIRCLEQ_FIRST "CIRCLEQ_HEAD *head"
-.Ft "struct TYPE *"
-.Fn CIRCLEQ_LAST "CIRCLEQ_HEAD *head"
-.Ft "struct TYPE *"
-.Fn CIRCLEQ_END "CIRCLEQ_HEAD *head"
-.Ft "struct TYPE *"
-.Fn CIRCLEQ_NEXT "struct TYPE *listelm" "FIELDNAME"
-.Ft "struct TYPE *"
-.Fn CIRCLEQ_PREV "struct TYPE *listelm" "FIELDNAME"
-.Ft int
-.Fn CIRCLEQ_EMPTY "CIRCLEQ_HEAD *head"
-.Fn CIRCLEQ_FOREACH "VARNAME" "CIRCLEQ_HEAD *head" "FIELDNAME"
-.Fn CIRCLEQ_FOREACH_SAFE "VARNAME" "CIRCLEQ_HEAD *head" "FIELDNAME"
"TEMP_VARNAME"
-.Fn CIRCLEQ_FOREACH_REVERSE "VARNAME" "CIRCLEQ_HEAD *head" "FIELDNAME"
-.Fn CIRCLEQ_FOREACH_REVERSE_SAFE "VARNAME" "CIRCLEQ_HEAD *head" "FIELDNAME"
"TEMP_VARNAME"
-.Ft void
-.Fn CIRCLEQ_INIT "CIRCLEQ_HEAD *head"
-.Ft void
-.Fn CIRCLEQ_INSERT_AFTER "CIRCLEQ_HEAD *head" "struct TYPE *listelm" "struct
TYPE *elm" "FIELDNAME"
-.Ft void
-.Fn CIRCLEQ_INSERT_BEFORE "CIRCLEQ_HEAD *head" "struct TYPE *listelm" "struct
TYPE *elm" "FIELDNAME"
-.Ft void
-.Fn CIRCLEQ_INSERT_HEAD "CIRCLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
-.Ft void
-.Fn CIRCLEQ_INSERT_TAIL "CIRCLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
-.Ft void
-.Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "struct TYPE *elm" "FIELDNAME"
-.Ft void
-.Fn CIRCLEQ_REPLACE "CIRCLEQ_HEAD *head" "struct TYPE *elm" "struct TYPE
*elm2" "FIELDNAME"
.Sh DESCRIPTION
-These macros define and operate on five types of data structures:
-singly-linked lists, simple queues, lists, tail queues, and circular queues.
-All five structures support the following functionality:
+These macros define and operate on four types of data structures:
+singly-linked lists, simple queues, lists, and tail queues.
+All four structures support the following functionality:
.Pp
.Bl -enum -compact -offset indent
.It
@@ -283,7 +230,7 @@ Removal of an entry from the head of the
Forward traversal through the list.
.El
.Pp
-Singly-linked lists are the simplest of the five data structures
+Singly-linked lists are the simplest of the four data structures
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.
@@ -310,8 +257,8 @@ than singly-linked lists.
Simple queues are ideal for applications with large datasets and
few or no removals, or for implementing a FIFO queue.
.Pp
-All doubly linked types of data structures (lists, tail queues, and circle
-queues) additionally allow:
+All doubly linked types of data structures (lists and tail queues)
+additionally allow:
.Pp
.Bl -enum -compact -offset indent
.It
@@ -354,27 +301,10 @@ Code size is about 15% greater and opera
than singly-linked lists.
.El
.Pp
-Circular queues add the following functionality:
-.Pp
-.Bl -enum -compact -offset indent
-.It
-Entries can be added at the end of a list.
-.It
-They may be traversed backwards, from tail to head.
-.El
-.Pp
-However:
-.Pp
-.Bl -enum -compact -offset indent
-.It
-All list insertions and removals must specify the head of the list.
-.It
-Each head entry requires two pointers rather than one.
-.It
-The termination condition for traversal is more complex.
-.It
-Code size is about 40% greater and operations run about 45% slower than lists.
-.El
+An additional type of data structure, circular queues, violated the C
+language aliasing rules and were miscompiled as a result.
+All code using them should be converted to another structure;
+tail queues are usually the easiest to convert to.
.Pp
In the macro definitions,
.Fa TYPE
@@ -382,9 +312,8 @@ is the name tag of a user defined struct
.Li SLIST_ENTRY ,
.Li LIST_ENTRY ,
.Li SIMPLEQ_ENTRY ,
-.Li TAILQ_ENTRY ,
or
-.Li CIRCLEQ_ENTRY ,
+.Li TAILQ_ENTRY ,
named
.Fa FIELDNAME .
The argument
@@ -394,9 +323,8 @@ using the macros
.Fn SLIST_HEAD ,
.Fn LIST_HEAD ,
.Fn SIMPLEQ_HEAD ,
-.Fn TAILQ_HEAD ,
or
-.Fn CIRCLEQ_HEAD .
+.Fn TAILQ_HEAD .
See the examples below for further explanation of how these macros are used.
.Sh SINGLY-LINKED LISTS
A singly-linked list is headed by a structure defined by the
@@ -972,164 +900,6 @@ while ((np = TAILQ_FIRST(&head))) {
}
.Ed
-.Sh CIRCULAR QUEUES
-A circular queue is headed by a structure defined by the
-.Fn CIRCLEQ_HEAD
-macro.
-This structure contains a pair of pointers,
-one to the first element in the circular queue and the other to the
-last element in the circular queue.
-The elements are doubly linked so that an arbitrary element can be
-removed without traversing the queue.
-New elements can be added to the queue after an existing element,
-before an existing element, at the head of the queue, or at the end
-of the queue.
-A
-.Fa CIRCLEQ_HEAD
-structure is declared as follows:
-.Bd -literal -offset indent
-CIRCLEQ_HEAD(HEADNAME, TYPE) head;
-.Ed
-.Pp
-where
-.Fa HEADNAME
-is the name of the structure to be defined, and struct
-.Fa 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:
-.Bd -literal -offset indent
-struct HEADNAME *headp;
-.Ed
-.Pp
-(The names
-.Li head
-and
-.Li headp
-are user selectable.)
-.Pp
-The
-.Fn CIRCLEQ_ENTRY
-macro declares a structure that connects the elements in the circular queue.
-.Pp
-The
-.Fn CIRCLEQ_INIT
-macro initializes the circular queue referenced by
-.Fa head .
-.Pp
-The circular queue can also be initialized statically by using the
-.Fn CIRCLEQ_HEAD_INITIALIZER
-macro.
-.Pp
-The
-.Fn CIRCLEQ_INSERT_HEAD
-macro inserts the new element
-.Fa elm
-at the head of the circular queue.
-.Pp
-The
-.Fn CIRCLEQ_INSERT_TAIL
-macro inserts the new element
-.Fa elm
-at the end of the circular queue.
-.Pp
-The
-.Fn CIRCLEQ_INSERT_AFTER
-macro inserts the new element
-.Fa elm
-after the element
-.Fa listelm .
-.Pp
-The
-.Fn CIRCLEQ_INSERT_BEFORE
-macro inserts the new element
-.Fa elm
-before the element
-.Fa listelm .
-.Pp
-The
-.Fn CIRCLEQ_REMOVE
-macro removes the element
-.Fa elm
-from the circular queue.
-.Pp
-The
-.Fn CIRCLEQ_REPLACE
-macro replaces the list element
-.Fa elm
-with the new element
-.Fa elm2 .
-.Pp
-The
-.Fn CIRCLEQ_FIRST ,
-.Fn CIRCLEQ_LAST ,
-.Fn CIRCLEQ_END ,
-.Fn CIRCLEQ_NEXT
-and
-.Fn CIRCLEQ_PREV
-macros can be used to traverse a circular queue.
-The
-.Fn CIRCLEQ_FOREACH
-is used for circular queue forward traversal:
-.Bd -literal -offset indent
-CIRCLEQ_FOREACH(np, head, FIELDNAME)
-.Ed
-.Pp
-The
-.Fn CIRCLEQ_FOREACH_REVERSE
-macro acts like
-.Fn CIRCLEQ_FOREACH
-but traverses the circular queue backwards.
-.Pp
-The macros
-.Fn CIRCLEQ_FOREACH_SAFE
-and
-.Fn CIRCLEQ_FOREACH_REVERSE_SAFE
-traverse the list referenced by head
-in a forward or reverse direction respectively,
-assigning each element in turn to var.
-However, unlike their unsafe counterparts,
-they permit both the removal of var
-as well as freeing it from within the loop safely
-without interfering with the traversal.
-.Pp
-The
-.Fn CIRCLEQ_EMPTY
-macro should be used to check whether a circular queue is empty.
-.Sh CIRCULAR QUEUE EXAMPLE
-.Bd -literal
-CIRCLEQ_HEAD(circleq, entry) head;
-struct entry {
- ...
- CIRCLEQ_ENTRY(entry) entries; /* Circular queue. */
- ...
-} *n1, *n2, *np;
-
-CIRCLEQ_INIT(&head); /* Initialize 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. */
-CIRCLEQ_FOREACH(np, &head, entries)
- np-> ...
- /* Reverse traversal. */
-CIRCLEQ_FOREACH_REVERSE(np, &head, entries)
- np-> ...
- /* Delete. */
-while (!CIRCLEQ_EMPTY(&head)) {
- n1 = CIRCLEQ_FIRST(&head);
- CIRCLEQ_REMOVE(&head, n1, entries);
- free(n1);
-}
-.Ed
.Sh NOTES
It is an error to assume the next and previous fields are preserved
after an element has been removed from a list or queue.
@@ -1143,7 +913,7 @@ The
.Fn SIMPLEQ_END
and
.Fn TAILQ_END
-macros are provided for symmetry with
+macros are provided for symmetry with the historical
.Fn CIRCLEQ_END .
They expand to
.Dv NULL
@@ -1169,3 +939,5 @@ The
.Nm queue
functions first appeared in
.Bx 4.4 .
+The historical circle queue macros were deprecated in
+.Ox 5.5 .