diff options
author | mckusick <mckusick@FreeBSD.org> | 2017-04-04 12:00:28 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2017-04-04 12:16:05 +0200 |
commit | 9998bd4b7c4596e47d8e0fbc6f1f370d096a6618 (patch) | |
tree | 68c65e9a1100a2e0498fb788c12922b9294344a8 /newlib | |
parent | 218c5e7d7264f1ed532d64d1932104fd8864b962 (diff) | |
download | cygnal-9998bd4b7c4596e47d8e0fbc6f1f370d096a6618.tar.gz cygnal-9998bd4b7c4596e47d8e0fbc6f1f370d096a6618.tar.bz2 cygnal-9998bd4b7c4596e47d8e0fbc6f1f370d096a6618.zip |
Add two new macros, SLIST_CONCAT and LIST_CONCAT
Add two new macros, SLIST_CONCAT and LIST_CONCAT. Note in both the
queue.h header file and in the queue.3 manual page that they are O(n) so
should be used only in low-usage paths with short lists (otherwise an
STAILQ or TAILQ should be used).
Reviewed by: kib
Diffstat (limited to 'newlib')
-rw-r--r-- | newlib/libc/include/sys/queue.h | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h index d6c821f7d..46bb69f29 100644 --- a/newlib/libc/include/sys/queue.h +++ b/newlib/libc/include/sys/queue.h @@ -76,6 +76,10 @@ * * For details on the use of these macros, see the queue(3) manual page. * + * Below is a summary of implemented functions where: + * + means the macro is available + * - means the macro is not available + * s means the macro is available but is slow (runs in O(n) time) * * SLIST LIST STAILQ TAILQ * _HEAD + + + + @@ -101,10 +105,10 @@ * _INSERT_BEFORE - + - + * _INSERT_AFTER + + + + * _INSERT_TAIL - - + + - * _CONCAT - - + + + * _CONCAT s s + + * _REMOVE_AFTER + - + - * _REMOVE_HEAD + - + - - * _REMOVE + + + + + * _REMOVE s + s + * _SWAP + + + + * */ @@ -183,6 +187,19 @@ struct { \ /* * Singly-linked List functions. */ +#define SLIST_CONCAT(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \ + if (curelm == NULL) { \ + if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \ + SLIST_INIT(head2); \ + } else if (SLIST_FIRST(head2) != NULL) { \ + while (SLIST_NEXT(curelm, field) != NULL) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \ + SLIST_INIT(head2); \ + } \ +} while (0) + #define SLIST_EMPTY(head) ((head)->slh_first == NULL) #define SLIST_FIRST(head) ((head)->slh_first) @@ -452,6 +469,23 @@ struct { \ #define QMD_LIST_CHECK_PREV(elm, field) #endif /* (_KERNEL && INVARIANTS) */ +#define LIST_CONCAT(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \ + if (curelm == NULL) { \ + if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \ + LIST_FIRST(head2)->field.le_prev = \ + &LIST_FIRST((head1)); \ + LIST_INIT(head2); \ + } \ + } else if (LIST_FIRST(head2) != NULL) { \ + while (LIST_NEXT(curelm, field) != NULL) \ + curelm = LIST_NEXT(curelm, field); \ + LIST_NEXT(curelm, field) = LIST_FIRST(head2); \ + LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \ + LIST_INIT(head2); \ + } \ +} while (0) + #define LIST_EMPTY(head) ((head)->lh_first == NULL) #define LIST_FIRST(head) ((head)->lh_first) |