mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
sys/queue.h: Add {LIST,TAILQ}_REPLACE().
MFC after: 1 week Obtained from: NetBSD Sponsored by: Klara, Inc. Reviewed by: cperciva, imp Differential Revision: https://reviews.freebsd.org/D44679
This commit is contained in:
parent
69fd60f1ea
commit
7f479dee48
|
@ -215,6 +215,7 @@ MLINKS+= queue.3 LIST_CLASS_ENTRY.3 \
|
||||||
queue.3 LIST_NEXT.3 \
|
queue.3 LIST_NEXT.3 \
|
||||||
queue.3 LIST_PREV.3 \
|
queue.3 LIST_PREV.3 \
|
||||||
queue.3 LIST_REMOVE.3 \
|
queue.3 LIST_REMOVE.3 \
|
||||||
|
queue.3 LIST_REPLACE.3 \
|
||||||
queue.3 LIST_SWAP.3 \
|
queue.3 LIST_SWAP.3 \
|
||||||
queue.3 SLIST_CLASS_ENTRY.3 \
|
queue.3 SLIST_CLASS_ENTRY.3 \
|
||||||
queue.3 SLIST_CLASS_HEAD.3 \
|
queue.3 SLIST_CLASS_HEAD.3 \
|
||||||
|
@ -283,6 +284,7 @@ MLINKS+= queue.3 LIST_CLASS_ENTRY.3 \
|
||||||
queue.3 TAILQ_NEXT.3 \
|
queue.3 TAILQ_NEXT.3 \
|
||||||
queue.3 TAILQ_PREV.3 \
|
queue.3 TAILQ_PREV.3 \
|
||||||
queue.3 TAILQ_REMOVE.3 \
|
queue.3 TAILQ_REMOVE.3 \
|
||||||
|
queue.3 TAILQ_REPLACE.3 \
|
||||||
queue.3 TAILQ_SWAP.3
|
queue.3 TAILQ_SWAP.3
|
||||||
MLINKS+= stats.3 stats_tpl_alloc.3 \
|
MLINKS+= stats.3 stats_tpl_alloc.3 \
|
||||||
stats.3 stats_tpl_fetch_allocid.3 \
|
stats.3 stats_tpl_fetch_allocid.3 \
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd September 8, 2016
|
.Dd April 8, 2024
|
||||||
.Dt QUEUE 3
|
.Dt QUEUE 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -90,6 +90,7 @@
|
||||||
.Nm LIST_NEXT ,
|
.Nm LIST_NEXT ,
|
||||||
.Nm LIST_PREV ,
|
.Nm LIST_PREV ,
|
||||||
.Nm LIST_REMOVE ,
|
.Nm LIST_REMOVE ,
|
||||||
|
.Nm LIST_REPLACE ,
|
||||||
.Nm LIST_SWAP ,
|
.Nm LIST_SWAP ,
|
||||||
.Nm TAILQ_CLASS_ENTRY ,
|
.Nm TAILQ_CLASS_ENTRY ,
|
||||||
.Nm TAILQ_CLASS_HEAD ,
|
.Nm TAILQ_CLASS_HEAD ,
|
||||||
|
@ -116,6 +117,7 @@
|
||||||
.Nm TAILQ_NEXT ,
|
.Nm TAILQ_NEXT ,
|
||||||
.Nm TAILQ_PREV ,
|
.Nm TAILQ_PREV ,
|
||||||
.Nm TAILQ_REMOVE ,
|
.Nm TAILQ_REMOVE ,
|
||||||
|
.Nm TAILQ_REPLACE ,
|
||||||
.Nm TAILQ_SWAP
|
.Nm TAILQ_SWAP
|
||||||
.Nd implementations of singly-linked lists, singly-linked tail queues,
|
.Nd implementations of singly-linked lists, singly-linked tail queues,
|
||||||
lists and tail queues
|
lists and tail queues
|
||||||
|
@ -185,6 +187,7 @@ lists and tail queues
|
||||||
.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_NEXT "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
|
.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
|
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
|
||||||
|
.Fn LIST_REPLACE "TYPE *elm" "TYPE *new" "LIST_ENTRY NAME"
|
||||||
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
|
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
|
||||||
.\"
|
.\"
|
||||||
.Fn TAILQ_CLASS_ENTRY "CLASSTYPE"
|
.Fn TAILQ_CLASS_ENTRY "CLASSTYPE"
|
||||||
|
@ -212,6 +215,7 @@ lists and tail queues
|
||||||
.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
|
.Fn TAILQ_NEXT "TYPE *elm" "TAILQ_ENTRY NAME"
|
||||||
.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "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_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
|
||||||
|
.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "TYPE *elm" "TYPE *new" "TAILQ_ENTRY NAME"
|
||||||
.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
|
.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
|
||||||
.\"
|
.\"
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
|
@ -963,6 +967,17 @@ removes the element
|
||||||
from the list.
|
from the list.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Fn LIST_REPLACE
|
||||||
|
replaces the element
|
||||||
|
.Fa elm
|
||||||
|
with
|
||||||
|
.Fa new
|
||||||
|
in the list.
|
||||||
|
The element
|
||||||
|
.Fa new
|
||||||
|
must not already be on a list.
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm LIST_SWAP
|
.Nm LIST_SWAP
|
||||||
swaps the contents of
|
swaps the contents of
|
||||||
.Fa head1
|
.Fa head1
|
||||||
|
@ -1221,6 +1236,17 @@ removes the element
|
||||||
from the tail queue.
|
from the tail queue.
|
||||||
.Pp
|
.Pp
|
||||||
The macro
|
The macro
|
||||||
|
.Fn TAILQ_REPLACE
|
||||||
|
replaces the element
|
||||||
|
.Fa elm
|
||||||
|
with
|
||||||
|
.Fa new
|
||||||
|
in the tail queue.
|
||||||
|
The element
|
||||||
|
.Fa new
|
||||||
|
must not already be on a list.
|
||||||
|
.Pp
|
||||||
|
The macro
|
||||||
.Nm TAILQ_SWAP
|
.Nm TAILQ_SWAP
|
||||||
swaps the contents of
|
swaps the contents of
|
||||||
.Fa head1
|
.Fa head1
|
||||||
|
@ -1235,7 +1261,7 @@ struct entry {
|
||||||
...
|
...
|
||||||
TAILQ_ENTRY(entry) entries; /* Tail queue. */
|
TAILQ_ENTRY(entry) entries; /* Tail queue. */
|
||||||
...
|
...
|
||||||
} *n1, *n2, *n3, *np;
|
} *n1, *n2, *n3, *n4, *np;
|
||||||
|
|
||||||
TAILQ_INIT(&head); /* Initialize the queue. */
|
TAILQ_INIT(&head); /* Initialize the queue. */
|
||||||
|
|
||||||
|
@ -1253,6 +1279,10 @@ TAILQ_INSERT_BEFORE(n2, n3, entries);
|
||||||
|
|
||||||
TAILQ_REMOVE(&head, n2, entries); /* Deletion. */
|
TAILQ_REMOVE(&head, n2, entries); /* Deletion. */
|
||||||
free(n2);
|
free(n2);
|
||||||
|
|
||||||
|
n4 = malloc(sizeof(struct entry)); /* Replacement. */
|
||||||
|
TAILQ_REPLACE(&head, n3, n4, entries);
|
||||||
|
free(n3);
|
||||||
/* Forward traversal. */
|
/* Forward traversal. */
|
||||||
TAILQ_FOREACH(np, &head, entries)
|
TAILQ_FOREACH(np, &head, entries)
|
||||||
np-> ...
|
np-> ...
|
||||||
|
|
|
@ -110,6 +110,7 @@
|
||||||
* _REMOVE_AFTER + - + -
|
* _REMOVE_AFTER + - + -
|
||||||
* _REMOVE_HEAD + + + +
|
* _REMOVE_HEAD + + + +
|
||||||
* _REMOVE s + s +
|
* _REMOVE s + s +
|
||||||
|
* _REPLACE - + - +
|
||||||
* _SWAP + + + +
|
* _SWAP + + + +
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -609,6 +610,21 @@ struct { \
|
||||||
TRASHIT(*oldprev); \
|
TRASHIT(*oldprev); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define LIST_REPLACE(elm, elm2, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.le_next); \
|
||||||
|
QMD_SAVELINK(oldprev, (elm)->field.le_prev); \
|
||||||
|
QMD_LIST_CHECK_NEXT(elm, field); \
|
||||||
|
QMD_LIST_CHECK_PREV(elm, field); \
|
||||||
|
LIST_NEXT((elm2), field) = LIST_NEXT((elm), field); \
|
||||||
|
if (LIST_NEXT((elm2), field) != NULL) \
|
||||||
|
LIST_NEXT((elm2), field)->field.le_prev = \
|
||||||
|
&(elm2)->field.le_next; \
|
||||||
|
(elm2)->field.le_prev = (elm)->field.le_prev; \
|
||||||
|
*(elm2)->field.le_prev = (elm2); \
|
||||||
|
TRASHIT(*oldnext); \
|
||||||
|
TRASHIT(*oldprev); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define LIST_SWAP(head1, head2, type, field) do { \
|
#define LIST_SWAP(head1, head2, type, field) do { \
|
||||||
QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
|
QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
|
||||||
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
|
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
|
||||||
|
@ -863,6 +879,24 @@ struct { \
|
||||||
QMD_TRACE_ELEM(&(elm)->field); \
|
QMD_TRACE_ELEM(&(elm)->field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define TAILQ_REPLACE(head, elm, elm2, field) do { \
|
||||||
|
QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \
|
||||||
|
QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \
|
||||||
|
QMD_TAILQ_CHECK_NEXT(elm, field); \
|
||||||
|
QMD_TAILQ_CHECK_PREV(elm, field); \
|
||||||
|
TAILQ_NEXT((elm2), field) = TAILQ_NEXT((elm), field); \
|
||||||
|
if (TAILQ_NEXT((elm2), field) != TAILQ_END(head)) \
|
||||||
|
TAILQ_NEXT((elm2), field)->field.tqe_prev = \
|
||||||
|
&(elm2)->field.tqe_next; \
|
||||||
|
else \
|
||||||
|
(head)->tqh_last = &(elm2)->field.tqe_next; \
|
||||||
|
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
|
||||||
|
*(elm2)->field.tqe_prev = (elm2); \
|
||||||
|
TRASHIT(*oldnext); \
|
||||||
|
TRASHIT(*oldprev); \
|
||||||
|
QMD_TRACE_ELEM(&(elm)->field); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_SWAP(head1, head2, type, field) do { \
|
#define TAILQ_SWAP(head1, head2, type, field) do { \
|
||||||
QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
|
QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
|
||||||
QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
|
QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
|
||||||
|
|
Loading…
Reference in a new issue