diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2024-04-08 18:16:40 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2024-04-08 18:16:46 +0000 |
commit | 7f479dee48973541da8c869b888b953161301c3b (patch) | |
tree | c1ff1ea3cecab221f593dd1b278a7e9228f06680 /sys/sys | |
parent | 69fd60f1ead5a86eeb0b18847dd71f7ae3fce4a0 (diff) | |
download | src-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.h | 34 |
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; \ |