aboutsummaryrefslogtreecommitdiff
path: root/sys/sys
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2024-04-08 18:16:40 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2024-04-08 18:16:46 +0000
commit7f479dee48973541da8c869b888b953161301c3b (patch)
treec1ff1ea3cecab221f593dd1b278a7e9228f06680 /sys/sys
parent69fd60f1ead5a86eeb0b18847dd71f7ae3fce4a0 (diff)
downloadsrc-7f479dee48973541da8c869b888b953161301c3b.tar.gz
src-7f479dee48973541da8c869b888b953161301c3b.zip
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
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/queue.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 2b11d54cdd45..0479d780fd85 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -110,6 +110,7 @@
* _REMOVE_AFTER + - + -
* _REMOVE_HEAD + + + +
* _REMOVE s + s +
+ * _REPLACE - + - +
* _SWAP + + + +
*
*/
@@ -609,6 +610,21 @@ struct { \
TRASHIT(*oldprev); \
} 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 { \
QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
@@ -863,6 +879,24 @@ struct { \
QMD_TRACE_ELEM(&(elm)->field); \
} 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 { \
QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \