Date: Wed, 19 Jul 2000 03:33:43 +0000 From: Tony Finch <dot@dotat.at> To: FreeBSD-gnats-submit@freebsd.org Subject: misc/20024: [PATCH] queue(3) concatenation macros Message-ID: <E13EkcB-000Ikz-00@hand.dotat.at>
next in thread | raw e-mail | index | archive | help
>Number: 20024 >Category: misc >Synopsis: [PATCH] queue(3) concatenation macros >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Tue Jul 18 20:40:00 PDT 2000 >Closed-Date: >Last-Modified: >Originator: Tony Finch <dot@dotat.at> >Release: FreeBSD 4.0-STABLE-20000705 i386 >Organization: dotat >Environment: >Description: The patch below adds a couple of macros to queue.h so that TAILQs and CIRCLEQs may be easily concatenated. It even includes documentation! >How-To-Repeat: >Fix: --- /usr/src/sys/sys/queue.h.orig Tue Jun 6 20:42:32 2000 +++ /usr/src/sys/sys/queue.h Wed Jul 19 03:15:10 2000 @@ -74,7 +74,8 @@ * linked so that an arbitrary element can be removed without a need to * traverse the list. New elements can be added to the list before or * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. + * the list. A tail queue may be traversed in either direction. Tail + * queues may be concated. * * A circle queue is headed by a pair of pointers, one to the head of the * list and the other to the tail of the list. The elements are doubly @@ -82,7 +83,7 @@ * traverse the list. New elements can be added to the list before or after * an existing element, at the head of the list, or at the end of the list. * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. + * complex end of list detection. Circle queues may be concatenated. * * For details on the use of these macros, see the queue(3) manual page. * @@ -104,6 +105,7 @@ * _INSERT_TAIL - - + + + * _REMOVE_HEAD + - + - - * _REMOVE + + + + + + * _CONCAT - - - + + * */ @@ -387,6 +389,15 @@ (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ } while (0) +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT(head2); \ + } \ +} while (0) + #define TAILQ_REMOVE(head, elm, field) do { \ if (((elm)->field.tqe_next) != NULL) \ (elm)->field.tqe_next->field.tqe_prev = \ @@ -471,6 +482,25 @@ else \ (head)->cqh_last->field.cqe_next = (elm); \ (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_CONCAT(head1, head2, field) do { \ + if (!CIRCLEQ_EMPTY(head2)) { \ + if (!CIRCLEQ_EMPTY(head1)) { \ + (head1)->cqh_last->field.cqe_next = \ + (head2)->cqh_first; \ + (head2)->cqh_first->field.cqe_prev = \ + (head1)->cqh_last; \ + } else { \ + (head1)->cqh_first = (head2)->cqh_first; \ + (head2)->cqh_first->field.cqe_prev = \ + (void *)(head1); \ + } \ + (head1)->cqh_last = (head2)->cqh_last; \ + (head2)->cqh_last->field.cqe_next = \ + (void *)(head1); \ + CIRCLEQ_INIT(head2); \ + } \ } while (0) #define CIRCLEQ_LAST(head) ((head)->cqh_last) --- /usr/src/share/man/man3/queue.3.orig Tue Jun 6 19:16:35 2000 +++ /usr/src/share/man/man3/queue.3 Wed Jul 19 03:25:39 2000 @@ -86,6 +86,7 @@ .Nm TAILQ_NEXT , .Nm TAILQ_PREV , .Nm TAILQ_REMOVE , +.Nm TAILQ_CONCAT , .Nm CIRCLEQ_EMPTY , .Nm CIRCLEQ_ENTRY , .Nm CIRCLEQ_FIRST , @@ -100,7 +101,8 @@ .Nm CIRCLE_LAST , .Nm CIRCLE_NEXT , .Nm CIRCLE_PREV , -.Nm CIRCLEQ_REMOVE +.Nm CIRCLEQ_REMOVE , +.Nm CIRCLEQ_CONCAT .Nd implementations of singly-linked lists, singly-linked tail queues, lists, tail queues, and circular queues .Sh SYNOPSIS @@ -159,6 +161,7 @@ .Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME" .Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME" .Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME" +.Fn TAILQ_CONCAT "TAILQ_HEAD *queue1" "TAILQ_HEAD *queue2" "TAILQ_ENTRY NAME" .\" .Fn CIRCLEQ_EMPTY "CIRCLEQ_HEAD *head" .Fn CIRCLEQ_ENTRY "TYPE" @@ -175,6 +178,7 @@ .Fn CIRCLEQ_NEXT "TYPE *elm" "CIRCLEQ_ENTRY NAME" .Fn CIRCLE_PREV "TYPE *elm" "CIRCLEQ_ENTRY NAME" .Fn CIRCLEQ_REMOVE "CIRCLEQ_HEAD *head" "TYPE *elm" "CIRCLEQ_ENTRY NAME" +.Fn CIRCLEQ_CONCAT "CIRCLEQ_HEAD *queue1" "CIRCLEQ_HEAD *queue2" "CIRCLEQ_ENTRY NAME" .Sh DESCRIPTION These macros define and operate on five types of data structures: singly-linked lists, singly-linked tail queues, lists, tail queues, @@ -245,6 +249,8 @@ Entries can be added at the end of a list. .It They may be traversed backwards, from tail to head. +.It +They may be concatenated. .El However: .Bl -enum -compact -offset indent @@ -263,6 +269,8 @@ Entries can be added at the end of a list. .It They may be traversed backwards, from tail to head. +.It +They may be concatenated. .El However: .Bl -enum -compact -offset indent @@ -826,6 +834,16 @@ removes the element .Fa elm from the tail queue. +.Pp +The macro +.Nm TAILQ_CONCAT +concatenates +.Fa queue2 +onto the end of +.Fa queue1 , +leaving +.Fa queue2 +empty. .Sh TAIL QUEUE EXAMPLE .Bd -literal TAILQ_HEAD(tailhead, entry) head; @@ -984,6 +1002,16 @@ removes the element .Fa elm from the circular queue. +.Pp +The macro +.Nm CIRCLEQ_CONCAT +concatenates +.Fa queue2 +onto the end of +.Fa queue1 , +leaving +.Fa queue2 +empty. .Sh CIRCULAR QUEUE EXAMPLE .Bd -literal CIRCLEQ_HEAD(circleq, entry) head; >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E13EkcB-000Ikz-00>