From 88ca88f3fd16768db694bc999e5f414bb58f94bb Mon Sep 17 00:00:00 2001 From: Gedare Bloom Date: Tue, 9 Jul 2024 16:05:31 -0600 Subject: [PATCH] cpukit/bsd-tree.h: prepend CPP with RTEMS_ scoping --- cpukit/include/linux/rbtree.h | 4 +- cpukit/include/rtems/score/bsd-tree.h | 796 +++++++-------- cpukit/include/rtems/score/rbtree.h | 42 +- cpukit/include/rtems/score/watchdogimpl.h | 8 +- cpukit/libfs/src/jffs2/src/fs-rtems.c | 2 +- cpukit/libfs/src/jffs2/src/readinode.c | 6 +- cpukit/score/src/rbtreeextract.c | 6 +- cpukit/score/src/rbtreeinsert.c | 9 +- cpukit/score/src/rbtreenext.c | 8 +- cpukit/score/src/rbtreeprev.c | 8 +- cpukit/score/src/rbtreereplace.c | 4 +- spec/build/testsuites/sptests/grp.yml | 2 + spec/build/testsuites/sptests/sptree01.yml | 19 + testsuites/sptests/sprbtree01/init.c | 12 +- testsuites/sptests/sptree01/init.c | 63 ++ testsuites/sptests/sptree01/sptree01.doc | 36 + testsuites/sptests/sptree01/sptree01.scn | 2 + testsuites/sptests/sptree01/sys/tree.h | 1062 ++++++++++++++++++++ 18 files changed, 1643 insertions(+), 446 deletions(-) create mode 100644 spec/build/testsuites/sptests/sptree01.yml create mode 100644 testsuites/sptests/sptree01/init.c create mode 100644 testsuites/sptests/sptree01/sptree01.doc create mode 100644 testsuites/sptests/sptree01/sptree01.scn create mode 100644 testsuites/sptests/sptree01/sys/tree.h diff --git a/cpukit/include/linux/rbtree.h b/cpukit/include/linux/rbtree.h index 2bd1e2bbf4..65e58cdc17 100644 --- a/cpukit/include/linux/rbtree.h +++ b/cpukit/include/linux/rbtree.h @@ -76,8 +76,8 @@ RTEMS_STATIC_ASSERT( rb_root_node ); -#undef RB_ROOT -#define RB_ROOT ( (struct rb_root) { NULL } ) +#undef RTEMS_RB_ROOT +#define RTEMS_RB_ROOT ( (struct rb_root) { NULL } ) #define rb_entry( p, container, field ) RTEMS_CONTAINER_OF( p, container, field ) diff --git a/cpukit/include/rtems/score/bsd-tree.h b/cpukit/include/rtems/score/bsd-tree.h index 8a99b3a017..dd4e2d1f5b 100644 --- a/cpukit/include/rtems/score/bsd-tree.h +++ b/cpukit/include/rtems/score/bsd-tree.h @@ -61,74 +61,74 @@ * The maximum height of a red-black tree is 2lg (n+1). */ -#define SPLAY_HEAD(name, type) \ +#define RTEMS_SPLAY_HEAD(name, type) \ struct name { \ struct type *sph_root; /* root of the tree */ \ } -#define SPLAY_INITIALIZER(root) \ +#define RTEMS_SPLAY_INITIALIZER(root) \ { NULL } -#define SPLAY_INIT(root) do { \ +#define RTEMS_SPLAY_INIT(root) do { \ (root)->sph_root = NULL; \ } while (/*CONSTCOND*/ 0) -#define SPLAY_ENTRY(type) \ +#define RTEMS_SPLAY_ENTRY(type) \ struct { \ struct type *spe_left; /* left element */ \ struct type *spe_right; /* right element */ \ } -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) +#define RTEMS_SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define RTEMS_SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define RTEMS_SPLAY_ROOT(head) (head)->sph_root +#define RTEMS_SPLAY_EMPTY(head) (RTEMS_SPLAY_ROOT(head) == NULL) -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ +/* RTEMS_SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold RTEMS_SPLAY_{RIGHT,LEFT} */ +#define RTEMS_SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + RTEMS_SPLAY_LEFT((head)->sph_root, field) = RTEMS_SPLAY_RIGHT(tmp, field); \ + RTEMS_SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (/*CONSTCOND*/ 0) -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ +#define RTEMS_SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + RTEMS_SPLAY_RIGHT((head)->sph_root, field) = RTEMS_SPLAY_LEFT(tmp, field); \ + RTEMS_SPLAY_LEFT(tmp, field) = (head)->sph_root; \ (head)->sph_root = tmp; \ } while (/*CONSTCOND*/ 0) -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ +#define RTEMS_SPLAY_LINKLEFT(head, tmp, field) do { \ + RTEMS_SPLAY_LEFT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ + (head)->sph_root = RTEMS_SPLAY_LEFT((head)->sph_root, field); \ } while (/*CONSTCOND*/ 0) -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ +#define RTEMS_SPLAY_LINKRIGHT(head, tmp, field) do { \ + RTEMS_SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = RTEMS_SPLAY_RIGHT((head)->sph_root, field); \ } while (/*CONSTCOND*/ 0) -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +#define RTEMS_SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + RTEMS_SPLAY_RIGHT(left, field) = RTEMS_SPLAY_LEFT((head)->sph_root, field); \ + RTEMS_SPLAY_LEFT(right, field) = RTEMS_SPLAY_RIGHT((head)->sph_root, field);\ + RTEMS_SPLAY_LEFT((head)->sph_root, field) = RTEMS_SPLAY_RIGHT(node, field); \ + RTEMS_SPLAY_RIGHT((head)->sph_root, field) = RTEMS_SPLAY_LEFT(node, field); \ } while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +#define RTEMS_SPLAY_PROTOTYPE(name, type, field, cmp) \ void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ -struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ -struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ +void name##_RTEMS_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_RTEMS_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_RTEMS_SPLAY_REMOVE(struct name *, struct type *); \ \ /* Finds the node with the same key as elm */ \ static __unused __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ +name##_RTEMS_SPLAY_FIND(struct name *head, struct type *elm) \ { \ - if (SPLAY_EMPTY(head)) \ + if (RTEMS_SPLAY_EMPTY(head)) \ return(NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) \ @@ -137,13 +137,13 @@ name##_SPLAY_FIND(struct name *head, struct type *elm) \ } \ \ static __unused __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +name##_RTEMS_SPLAY_NEXT(struct name *head, struct type *elm) \ { \ name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ + if (RTEMS_SPLAY_RIGHT(elm, field) != NULL) { \ + elm = RTEMS_SPLAY_RIGHT(elm, field); \ + while (RTEMS_SPLAY_LEFT(elm, field) != NULL) { \ + elm = RTEMS_SPLAY_LEFT(elm, field); \ } \ } else \ elm = NULL; \ @@ -151,33 +151,33 @@ name##_SPLAY_NEXT(struct name *head, struct type *elm) \ } \ \ static __unused __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ +name##_RTEMS_SPLAY_MIN_MAX(struct name *head, int val) \ { \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ + name##_RTEMS_SPLAY_MINMAX(head, val); \ + return (RTEMS_SPLAY_ROOT(head)); \ } /* Main splay operation. * Moves node close to the key of elm to top */ -#define SPLAY_GENERATE(name, type, field, cmp) \ +#define RTEMS_SPLAY_GENERATE(name, type, field, cmp) \ struct type * \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +name##_RTEMS_SPLAY_INSERT(struct name *head, struct type *elm) \ { \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + if (RTEMS_SPLAY_EMPTY(head)) { \ + RTEMS_SPLAY_LEFT(elm, field) = RTEMS_SPLAY_RIGHT(elm, field) = NULL; \ } else { \ int __comp; \ name##_SPLAY(head, elm); \ __comp = (cmp)(elm, (head)->sph_root); \ if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ + RTEMS_SPLAY_LEFT(elm, field) = RTEMS_SPLAY_LEFT((head)->sph_root, field);\ + RTEMS_SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + RTEMS_SPLAY_LEFT((head)->sph_root, field) = NULL; \ } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + RTEMS_SPLAY_RIGHT(elm, field) = RTEMS_SPLAY_RIGHT((head)->sph_root, field);\ + RTEMS_SPLAY_LEFT(elm, field) = (head)->sph_root; \ + RTEMS_SPLAY_RIGHT((head)->sph_root, field) = NULL; \ } else \ return ((head)->sph_root); \ } \ @@ -186,20 +186,20 @@ name##_SPLAY_INSERT(struct name *head, struct type *elm) \ } \ \ struct type * \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +name##_RTEMS_SPLAY_REMOVE(struct name *head, struct type *elm) \ { \ struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ + if (RTEMS_SPLAY_EMPTY(head)) \ return (NULL); \ name##_SPLAY(head, elm); \ if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + if (RTEMS_SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = RTEMS_SPLAY_RIGHT((head)->sph_root, field);\ } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + __tmp = RTEMS_SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = RTEMS_SPLAY_LEFT((head)->sph_root, field);\ name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + RTEMS_SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ } \ return (elm); \ } \ @@ -212,104 +212,104 @@ name##_SPLAY(struct name *head, struct type *elm) \ struct type __node, *__left, *__right, *__tmp; \ int __comp; \ \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + RTEMS_SPLAY_LEFT(&__node, field) = RTEMS_SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ + __tmp = RTEMS_SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + RTEMS_SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (RTEMS_SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ - SPLAY_LINKLEFT(head, __right, field); \ + RTEMS_SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + __tmp = RTEMS_SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + RTEMS_SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (RTEMS_SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ - SPLAY_LINKRIGHT(head, __left, field); \ + RTEMS_SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ + RTEMS_SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } \ \ /* Splay with either the minimum or the maximum element \ * Used to find minimum or maximum element in tree. \ */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +void name##_RTEMS_SPLAY_MINMAX(struct name *head, int __comp) \ { \ struct type __node, *__left, *__right, *__tmp; \ \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + RTEMS_SPLAY_LEFT(&__node, field) = RTEMS_SPLAY_RIGHT(&__node, field) = NULL;\ __left = __right = &__node; \ \ while (1) { \ if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ + __tmp = RTEMS_SPLAY_LEFT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + RTEMS_SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (RTEMS_SPLAY_LEFT((head)->sph_root, field) == NULL)\ break; \ } \ - SPLAY_LINKLEFT(head, __right, field); \ + RTEMS_SPLAY_LINKLEFT(head, __right, field); \ } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + __tmp = RTEMS_SPLAY_RIGHT((head)->sph_root, field); \ if (__tmp == NULL) \ break; \ if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + RTEMS_SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (RTEMS_SPLAY_RIGHT((head)->sph_root, field) == NULL)\ break; \ } \ - SPLAY_LINKRIGHT(head, __left, field); \ + RTEMS_SPLAY_LINKRIGHT(head, __left, field); \ } \ } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ + RTEMS_SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ } -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 +#define RTEMS_SPLAY_NEGINF -1 +#define RTEMS_SPLAY_INF 1 -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) +#define RTEMS_SPLAY_INSERT(name, x, y) name##_RTEMS_SPLAY_INSERT(x, y) +#define RTEMS_SPLAY_REMOVE(name, x, y) name##_RTEMS_SPLAY_REMOVE(x, y) +#define RTEMS_SPLAY_FIND(name, x, y) name##_RTEMS_SPLAY_FIND(x, y) +#define RTEMS_SPLAY_NEXT(name, x, y) name##_RTEMS_SPLAY_NEXT(x, y) +#define RTEMS_SPLAY_MIN(name, x) (RTEMS_SPLAY_EMPTY(x) ? NULL \ + : name##_RTEMS_SPLAY_MIN_MAX(x, RTEMS_SPLAY_NEGINF)) +#define RTEMS_SPLAY_MAX(name, x) (RTEMS_SPLAY_EMPTY(x) ? NULL \ + : name##_RTEMS_SPLAY_MIN_MAX(x, RTEMS_SPLAY_INF)) -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ +#define RTEMS_SPLAY_FOREACH(x, name, head) \ + for ((x) = RTEMS_SPLAY_MIN(name, head); \ (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) + (x) = RTEMS_SPLAY_NEXT(name, head, x)) /* Macros that define a red-black tree */ -#define RB_HEAD(name, type) \ +#define RTEMS_RB_HEAD(name, type) \ struct name { \ struct type *rbh_root; /* root of the tree */ \ } -#define RB_INITIALIZER(root) \ +#define RTEMS_RB_INITIALIZER(root) \ { NULL } -#define RB_INIT(root) do { \ +#define RTEMS_RB_INIT(root) do { \ (root)->rbh_root = NULL; \ } while (/*CONSTCOND*/ 0) -#define RB_BLACK 0 -#define RB_RED 1 -#define RB_ENTRY(type) \ +#define RTEMS_RB_BLACK 0 +#define RTEMS_RB_RED 1 +#define RTEMS_RB_ENTRY(type) \ struct { \ struct type *rbe_left; /* left element */ \ struct type *rbe_right; /* right element */ \ @@ -317,104 +317,104 @@ struct { \ int rbe_color; /* node color */ \ } -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ISRED(elm, field) ((elm) != NULL && RB_COLOR(elm, field) == RB_RED) -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) +#define RTEMS_RB_LEFT(elm, field) (elm)->field.rbe_left +#define RTEMS_RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RTEMS_RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RTEMS_RB_COLOR(elm, field) (elm)->field.rbe_color +#define RTEMS_RB_ISRED(elm, field) ((elm) != NULL && RTEMS_RB_COLOR(elm, field) == RTEMS_RB_RED) +#define RTEMS_RB_ROOT(head) (head)->rbh_root +#define RTEMS_RB_EMPTY(head) (RTEMS_RB_ROOT(head) == NULL) -#define RB_SET_PARENT(dst, src, field) do { \ - RB_PARENT(dst, field) = src; \ +#define RTEMS_RB_SET_PARENT(dst, src, field) do { \ + RTEMS_RB_PARENT(dst, field) = src; \ } while (/*CONSTCOND*/ 0) -#define RB_SET(elm, parent, field) do { \ - RB_SET_PARENT(elm, parent, field); \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ +#define RTEMS_RB_SET(elm, parent, field) do { \ + RTEMS_RB_SET_PARENT(elm, parent, field); \ + RTEMS_RB_LEFT(elm, field) = RTEMS_RB_RIGHT(elm, field) = NULL; \ + RTEMS_RB_COLOR(elm, field) = RTEMS_RB_RED; \ } while (/*CONSTCOND*/ 0) -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ +#define RTEMS_RB_SET_BLACKRED(black, red, field) do { \ + RTEMS_RB_COLOR(black, field) = RTEMS_RB_BLACK; \ + RTEMS_RB_COLOR(red, field) = RTEMS_RB_RED; \ } while (/*CONSTCOND*/ 0) /* * Something to be invoked in a loop at the root of every modified subtree, * from the bottom up to the root, to update augmented node data. */ -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) break +#ifndef RTEMS_RB_AUGMENT +#define RTEMS_RB_AUGMENT(x) break #endif -#define RB_SWAP_CHILD(head, out, in, field) do { \ - if (RB_PARENT(out, field) == NULL) \ - RB_ROOT(head) = (in); \ - else if ((out) == RB_LEFT(RB_PARENT(out, field), field)) \ - RB_LEFT(RB_PARENT(out, field), field) = (in); \ +#define RTEMS_RB_SWAP_CHILD(head, out, in, field) do { \ + if (RTEMS_RB_PARENT(out, field) == NULL) \ + RTEMS_RB_ROOT(head) = (in); \ + else if ((out) == RTEMS_RB_LEFT(RTEMS_RB_PARENT(out, field), field)) \ + RTEMS_RB_LEFT(RTEMS_RB_PARENT(out, field), field) = (in); \ else \ - RB_RIGHT(RB_PARENT(out, field), field) = (in); \ + RTEMS_RB_RIGHT(RTEMS_RB_PARENT(out, field), field) = (in); \ } while (/*CONSTCOND*/ 0) -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ - RB_SET_PARENT(RB_RIGHT(elm, field), elm, field); \ +#define RTEMS_RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RTEMS_RB_RIGHT(elm, field); \ + if ((RTEMS_RB_RIGHT(elm, field) = RTEMS_RB_LEFT(tmp, field)) != NULL) { \ + RTEMS_RB_SET_PARENT(RTEMS_RB_RIGHT(elm, field), elm, field); \ } \ - RB_SET_PARENT(tmp, RB_PARENT(elm, field), field); \ - RB_SWAP_CHILD(head, elm, tmp, field); \ - RB_LEFT(tmp, field) = (elm); \ - RB_SET_PARENT(elm, tmp, field); \ - RB_AUGMENT(elm); \ + RTEMS_RB_SET_PARENT(tmp, RTEMS_RB_PARENT(elm, field), field); \ + RTEMS_RB_SWAP_CHILD(head, elm, tmp, field); \ + RTEMS_RB_LEFT(tmp, field) = (elm); \ + RTEMS_RB_SET_PARENT(elm, tmp, field); \ + RTEMS_RB_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ - RB_SET_PARENT(RB_LEFT(elm, field), elm, field); \ +#define RTEMS_RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RTEMS_RB_LEFT(elm, field); \ + if ((RTEMS_RB_LEFT(elm, field) = RTEMS_RB_RIGHT(tmp, field)) != NULL) { \ + RTEMS_RB_SET_PARENT(RTEMS_RB_LEFT(elm, field), elm, field); \ } \ - RB_SET_PARENT(tmp, RB_PARENT(elm, field), field); \ - RB_SWAP_CHILD(head, elm, tmp, field); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_SET_PARENT(elm, tmp, field); \ - RB_AUGMENT(elm); \ + RTEMS_RB_SET_PARENT(tmp, RTEMS_RB_PARENT(elm, field), field); \ + RTEMS_RB_SWAP_CHILD(head, elm, tmp, field); \ + RTEMS_RB_RIGHT(tmp, field) = (elm); \ + RTEMS_RB_SET_PARENT(elm, tmp, field); \ + RTEMS_RB_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) /* - * The RB_PARENT_ROTATE_LEFT() and RB_PARENT_ROTATE_RIGHT() rotations are - * specialized versions of RB_ROTATE_LEFT() and RB_ROTATE_RIGHT() which may be + * The RTEMS_RB_PARENT_ROTATE_LEFT() and RTEMS_RB_PARENT_ROTATE_RIGHT() rotations are + * specialized versions of RTEMS_RB_ROTATE_LEFT() and RTEMS_RB_ROTATE_RIGHT() which may be * used if the parent node exists and the direction of the child element is * known. */ -#define RB_PARENT_ROTATE_LEFT(parent, left, tmp, field) do { \ - (tmp) = RB_RIGHT(left, field); \ - if ((RB_RIGHT(left, field) = RB_LEFT(tmp, field)) != NULL) { \ - RB_SET_PARENT(RB_RIGHT(left, field), left, field); \ +#define RTEMS_RB_PARENT_ROTATE_LEFT(parent, left, tmp, field) do { \ + (tmp) = RTEMS_RB_RIGHT(left, field); \ + if ((RTEMS_RB_RIGHT(left, field) = RTEMS_RB_LEFT(tmp, field)) != NULL) { \ + RTEMS_RB_SET_PARENT(RTEMS_RB_RIGHT(left, field), left, field); \ } \ - RB_SET_PARENT(tmp, parent, field); \ - RB_LEFT(parent, field) = (tmp); \ - RB_LEFT(tmp, field) = (left); \ - RB_SET_PARENT(left, tmp, field); \ - RB_AUGMENT(left); \ + RTEMS_RB_SET_PARENT(tmp, parent, field); \ + RTEMS_RB_LEFT(parent, field) = (tmp); \ + RTEMS_RB_LEFT(tmp, field) = (left); \ + RTEMS_RB_SET_PARENT(left, tmp, field); \ + RTEMS_RB_AUGMENT(left); \ } while (/*CONSTCOND*/ 0) -#define RB_PARENT_ROTATE_RIGHT(parent, right, tmp, field) do { \ - (tmp) = RB_LEFT(right, field); \ - if ((RB_LEFT(right, field) = RB_RIGHT(tmp, field)) != NULL) { \ - RB_SET_PARENT(RB_LEFT(right, field), right, field); \ +#define RTEMS_RB_PARENT_ROTATE_RIGHT(parent, right, tmp, field) do { \ + (tmp) = RTEMS_RB_LEFT(right, field); \ + if ((RTEMS_RB_LEFT(right, field) = RTEMS_RB_RIGHT(tmp, field)) != NULL) { \ + RTEMS_RB_SET_PARENT(RTEMS_RB_LEFT(right, field), right, field); \ } \ - RB_SET_PARENT(tmp, parent, field); \ - RB_RIGHT(parent, field) = (tmp); \ - RB_RIGHT(tmp, field) = (right); \ - RB_SET_PARENT(right, tmp, field); \ - RB_AUGMENT(right); \ + RTEMS_RB_SET_PARENT(tmp, parent, field); \ + RTEMS_RB_RIGHT(parent, field) = (tmp); \ + RTEMS_RB_RIGHT(tmp, field) = (right); \ + RTEMS_RB_SET_PARENT(right, tmp, field); \ + RTEMS_RB_AUGMENT(right); \ } while (/*CONSTCOND*/ 0) /* - * The RB_RED_ROTATE_LEFT() and RB_RED_ROTATE_RIGHT() rotations are specialized - * versions of RB_ROTATE_LEFT() and RB_ROTATE_RIGHT() which may be used if we + * The RTEMS_RB_RED_ROTATE_LEFT() and RTEMS_RB_RED_ROTATE_RIGHT() rotations are specialized + * versions of RTEMS_RB_ROTATE_LEFT() and RTEMS_RB_ROTATE_RIGHT() which may be used if we * rotate an element with a red child which has a black sibling. Such a red * node must have at least two child nodes so that the following red-black tree * invariant is fulfilled: @@ -429,436 +429,436 @@ struct { \ * BLACK BLACK */ -#define RB_RED_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - RB_RIGHT(elm, field) = RB_LEFT(tmp, field); \ - RB_SET_PARENT(RB_RIGHT(elm, field), elm, field); \ - RB_SET_PARENT(tmp, RB_PARENT(elm, field), field); \ - RB_SWAP_CHILD(head, elm, tmp, field); \ - RB_LEFT(tmp, field) = (elm); \ - RB_SET_PARENT(elm, tmp, field); \ - RB_AUGMENT(elm); \ +#define RTEMS_RB_RED_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RTEMS_RB_RIGHT(elm, field); \ + RTEMS_RB_RIGHT(elm, field) = RTEMS_RB_LEFT(tmp, field); \ + RTEMS_RB_SET_PARENT(RTEMS_RB_RIGHT(elm, field), elm, field); \ + RTEMS_RB_SET_PARENT(tmp, RTEMS_RB_PARENT(elm, field), field); \ + RTEMS_RB_SWAP_CHILD(head, elm, tmp, field); \ + RTEMS_RB_LEFT(tmp, field) = (elm); \ + RTEMS_RB_SET_PARENT(elm, tmp, field); \ + RTEMS_RB_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) -#define RB_RED_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - RB_LEFT(elm, field) = RB_RIGHT(tmp, field); \ - RB_SET_PARENT(RB_LEFT(elm, field), elm, field); \ - RB_SET_PARENT(tmp, RB_PARENT(elm, field), field); \ - RB_SWAP_CHILD(head, elm, tmp, field); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_SET_PARENT(elm, tmp, field); \ - RB_AUGMENT(elm); \ +#define RTEMS_RB_RED_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RTEMS_RB_LEFT(elm, field); \ + RTEMS_RB_LEFT(elm, field) = RTEMS_RB_RIGHT(tmp, field); \ + RTEMS_RB_SET_PARENT(RTEMS_RB_LEFT(elm, field), elm, field); \ + RTEMS_RB_SET_PARENT(tmp, RTEMS_RB_PARENT(elm, field), field); \ + RTEMS_RB_SWAP_CHILD(head, elm, tmp, field); \ + RTEMS_RB_RIGHT(tmp, field) = (elm); \ + RTEMS_RB_SET_PARENT(elm, tmp, field); \ + RTEMS_RB_AUGMENT(elm); \ } while (/*CONSTCOND*/ 0) /* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) -#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) -#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ - RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \ - RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \ - RB_PROTOTYPE_INSERT(name, type, attr); \ - RB_PROTOTYPE_REMOVE(name, type, attr); \ - RB_PROTOTYPE_FIND(name, type, attr); \ - RB_PROTOTYPE_NFIND(name, type, attr); \ - RB_PROTOTYPE_NEXT(name, type, attr); \ - RB_PROTOTYPE_PREV(name, type, attr); \ - RB_PROTOTYPE_MINMAX(name, type, attr); \ - RB_PROTOTYPE_REINSERT(name, type, attr); -#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \ - attr void name##_RB_INSERT_COLOR(struct name *, struct type *) -#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \ - attr void name##_RB_REMOVE_COLOR(struct name *, struct type *) -#define RB_PROTOTYPE_REMOVE(name, type, attr) \ - attr struct type *name##_RB_REMOVE(struct name *, struct type *) -#define RB_PROTOTYPE_INSERT(name, type, attr) \ - attr struct type *name##_RB_INSERT(struct name *, struct type *) -#define RB_PROTOTYPE_FIND(name, type, attr) \ - attr struct type *name##_RB_FIND(struct name *, struct type *) -#define RB_PROTOTYPE_NFIND(name, type, attr) \ - attr struct type *name##_RB_NFIND(struct name *, struct type *) -#define RB_PROTOTYPE_NEXT(name, type, attr) \ - attr struct type *name##_RB_NEXT(struct type *) -#define RB_PROTOTYPE_PREV(name, type, attr) \ - attr struct type *name##_RB_PREV(struct type *) -#define RB_PROTOTYPE_MINMAX(name, type, attr) \ - attr struct type *name##_RB_MINMAX(struct name *, int) -#define RB_PROTOTYPE_REINSERT(name, type, attr) \ - attr struct type *name##_RB_REINSERT(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE(name, type, field, cmp) \ + RTEMS_RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RTEMS_RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RTEMS_RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) +#define RTEMS_RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ + RTEMS_RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \ + RTEMS_RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \ + RTEMS_RB_PROTOTYPE_INSERT(name, type, attr); \ + RTEMS_RB_PROTOTYPE_REMOVE(name, type, attr); \ + RTEMS_RB_PROTOTYPE_FIND(name, type, attr); \ + RTEMS_RB_PROTOTYPE_NFIND(name, type, attr); \ + RTEMS_RB_PROTOTYPE_NEXT(name, type, attr); \ + RTEMS_RB_PROTOTYPE_PREV(name, type, attr); \ + RTEMS_RB_PROTOTYPE_MINMAX(name, type, attr); \ + RTEMS_RB_PROTOTYPE_REINSERT(name, type, attr); +#define RTEMS_RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \ + attr void name##_RTEMS_RB_INSERT_COLOR(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \ + attr void name##_RTEMS_RB_REMOVE_COLOR(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_REMOVE(name, type, attr) \ + attr struct type *name##_RTEMS_RB_REMOVE(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_INSERT(name, type, attr) \ + attr struct type *name##_RTEMS_RB_INSERT(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_FIND(name, type, attr) \ + attr struct type *name##_RTEMS_RB_FIND(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_NFIND(name, type, attr) \ + attr struct type *name##_RTEMS_RB_NFIND(struct name *, struct type *) +#define RTEMS_RB_PROTOTYPE_NEXT(name, type, attr) \ + attr struct type *name##_RTEMS_RB_NEXT(struct type *) +#define RTEMS_RB_PROTOTYPE_PREV(name, type, attr) \ + attr struct type *name##_RTEMS_RB_PREV(struct type *) +#define RTEMS_RB_PROTOTYPE_MINMAX(name, type, attr) \ + attr struct type *name##_RTEMS_RB_MINMAX(struct name *, int) +#define RTEMS_RB_PROTOTYPE_REINSERT(name, type, attr) \ + attr struct type *name##_RTEMS_RB_REINSERT(struct name *, struct type *) /* Main rb operation. * Moves node close to the key of elm to top */ -#define RB_GENERATE(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp,) -#define RB_GENERATE_STATIC(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) -#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ - RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ - RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ - RB_GENERATE_INSERT(name, type, field, cmp, attr) \ - RB_GENERATE_REMOVE(name, type, field, attr) \ - RB_GENERATE_FIND(name, type, field, cmp, attr) \ - RB_GENERATE_NFIND(name, type, field, cmp, attr) \ - RB_GENERATE_NEXT(name, type, field, attr) \ - RB_GENERATE_PREV(name, type, field, attr) \ - RB_GENERATE_MINMAX(name, type, field, attr) \ - RB_GENERATE_REINSERT(name, type, field, cmp, attr) +#define RTEMS_RB_GENERATE(name, type, field, cmp) \ + RTEMS_RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RTEMS_RB_GENERATE_STATIC(name, type, field, cmp) \ + RTEMS_RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) +#define RTEMS_RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ + RTEMS_RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ + RTEMS_RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ + RTEMS_RB_GENERATE_INSERT(name, type, field, cmp, attr) \ + RTEMS_RB_GENERATE_REMOVE(name, type, field, attr) \ + RTEMS_RB_GENERATE_FIND(name, type, field, cmp, attr) \ + RTEMS_RB_GENERATE_NFIND(name, type, field, cmp, attr) \ + RTEMS_RB_GENERATE_NEXT(name, type, field, attr) \ + RTEMS_RB_GENERATE_PREV(name, type, field, attr) \ + RTEMS_RB_GENERATE_MINMAX(name, type, field, attr) \ + RTEMS_RB_GENERATE_REINSERT(name, type, field, cmp, attr) -#define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ attr void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +name##_RTEMS_RB_INSERT_COLOR(struct name *head, struct type *elm) \ { \ struct type *parent, *gparent, *tmp; \ - while (RB_ISRED((parent = RB_PARENT(elm, field)), field)) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (RB_ISRED(tmp, field)) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ + while (RTEMS_RB_ISRED((parent = RTEMS_RB_PARENT(elm, field)), field)) { \ + gparent = RTEMS_RB_PARENT(parent, field); \ + if (parent == RTEMS_RB_LEFT(gparent, field)) { \ + tmp = RTEMS_RB_RIGHT(gparent, field); \ + if (RTEMS_RB_ISRED(tmp, field)) { \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_BLACK; \ + RTEMS_RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_PARENT_ROTATE_LEFT(gparent, parent, \ + if (RTEMS_RB_RIGHT(parent, field) == elm) { \ + RTEMS_RB_PARENT_ROTATE_LEFT(gparent, parent, \ tmp, field); \ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + RTEMS_RB_SET_BLACKRED(parent, gparent, field); \ + RTEMS_RB_ROTATE_RIGHT(head, gparent, tmp, field); \ } else { \ - tmp = RB_LEFT(gparent, field); \ - if (RB_ISRED(tmp, field)) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ + tmp = RTEMS_RB_LEFT(gparent, field); \ + if (RTEMS_RB_ISRED(tmp, field)) { \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_BLACK; \ + RTEMS_RB_SET_BLACKRED(parent, gparent, field);\ elm = gparent; \ continue; \ } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_PARENT_ROTATE_RIGHT(gparent, parent, \ + if (RTEMS_RB_LEFT(parent, field) == elm) { \ + RTEMS_RB_PARENT_ROTATE_RIGHT(gparent, parent, \ tmp, field); \ tmp = parent; \ parent = elm; \ elm = tmp; \ } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ + RTEMS_RB_SET_BLACKRED(parent, gparent, field); \ + RTEMS_RB_ROTATE_LEFT(head, gparent, tmp, field); \ } \ } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ + RTEMS_RB_COLOR(head->rbh_root, field) = RTEMS_RB_BLACK; \ } -#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ attr void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent) \ +name##_RTEMS_RB_REMOVE_COLOR(struct name *head, struct type *parent) \ { \ struct type *elm, *tmp; \ elm = NULL; \ do { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_RED_ROTATE_LEFT(head, parent, tmp, field); \ - tmp = RB_RIGHT(parent, field); \ + if (RTEMS_RB_LEFT(parent, field) == elm) { \ + tmp = RTEMS_RB_RIGHT(parent, field); \ + if (RTEMS_RB_COLOR(tmp, field) == RTEMS_RB_RED) { \ + RTEMS_RB_SET_BLACKRED(tmp, parent, field); \ + RTEMS_RB_RED_ROTATE_LEFT(head, parent, tmp, field); \ + tmp = RTEMS_RB_RIGHT(parent, field); \ } \ - if (RB_ISRED(RB_RIGHT(tmp, field), field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \ - else if (RB_ISRED(RB_LEFT(tmp, field), field)) { \ + if (RTEMS_RB_ISRED(RTEMS_RB_RIGHT(tmp, field), field)) \ + RTEMS_RB_COLOR(RTEMS_RB_RIGHT(tmp, field), field) = RTEMS_RB_BLACK; \ + else if (RTEMS_RB_ISRED(RTEMS_RB_LEFT(tmp, field), field)) { \ struct type *oleft; \ - RB_PARENT_ROTATE_RIGHT(parent, tmp, \ + RTEMS_RB_PARENT_ROTATE_RIGHT(parent, tmp, \ oleft, field); \ - RB_COLOR(oleft, field) = RB_BLACK; \ + RTEMS_RB_COLOR(oleft, field) = RTEMS_RB_BLACK; \ tmp = oleft; \ } else { \ - RB_COLOR(tmp, field) = RB_RED; \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_RED; \ elm = parent; \ - parent = RB_PARENT(elm, field); \ + parent = RTEMS_RB_PARENT(elm, field); \ continue; \ } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ - RB_COLOR(parent, field) = RB_BLACK; \ - RB_ROTATE_LEFT(head, parent, tmp, field); \ - elm = RB_ROOT(head); \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_COLOR(parent, field); \ + RTEMS_RB_COLOR(parent, field) = RTEMS_RB_BLACK; \ + RTEMS_RB_ROTATE_LEFT(head, parent, tmp, field); \ + elm = RTEMS_RB_ROOT(head); \ break; \ } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_RED_ROTATE_RIGHT(head, parent, tmp, field); \ - tmp = RB_LEFT(parent, field); \ + tmp = RTEMS_RB_LEFT(parent, field); \ + if (RTEMS_RB_COLOR(tmp, field) == RTEMS_RB_RED) { \ + RTEMS_RB_SET_BLACKRED(tmp, parent, field); \ + RTEMS_RB_RED_ROTATE_RIGHT(head, parent, tmp, field); \ + tmp = RTEMS_RB_LEFT(parent, field); \ } \ - if (RB_ISRED(RB_LEFT(tmp, field), field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \ - else if (RB_ISRED(RB_RIGHT(tmp, field), field)) { \ + if (RTEMS_RB_ISRED(RTEMS_RB_LEFT(tmp, field), field)) \ + RTEMS_RB_COLOR(RTEMS_RB_LEFT(tmp, field), field) = RTEMS_RB_BLACK; \ + else if (RTEMS_RB_ISRED(RTEMS_RB_RIGHT(tmp, field), field)) { \ struct type *oright; \ - RB_PARENT_ROTATE_LEFT(parent, tmp, \ + RTEMS_RB_PARENT_ROTATE_LEFT(parent, tmp, \ oright, field); \ - RB_COLOR(oright, field) = RB_BLACK; \ + RTEMS_RB_COLOR(oright, field) = RTEMS_RB_BLACK; \ tmp = oright; \ } else { \ - RB_COLOR(tmp, field) = RB_RED; \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_RED; \ elm = parent; \ - parent = RB_PARENT(elm, field); \ + parent = RTEMS_RB_PARENT(elm, field); \ continue; \ } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ - RB_COLOR(parent, field) = RB_BLACK; \ - RB_ROTATE_RIGHT(head, parent, tmp, field); \ - elm = RB_ROOT(head); \ + RTEMS_RB_COLOR(tmp, field) = RTEMS_RB_COLOR(parent, field); \ + RTEMS_RB_COLOR(parent, field) = RTEMS_RB_BLACK; \ + RTEMS_RB_ROTATE_RIGHT(head, parent, tmp, field); \ + elm = RTEMS_RB_ROOT(head); \ break; \ } \ - } while (RB_COLOR(elm, field) == RB_BLACK && parent != NULL); \ - RB_COLOR(elm, field) = RB_BLACK; \ + } while (RTEMS_RB_COLOR(elm, field) == RTEMS_RB_BLACK && parent != NULL); \ + RTEMS_RB_COLOR(elm, field) = RTEMS_RB_BLACK; \ } -#define RB_GENERATE_REMOVE(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_REMOVE(name, type, field, attr) \ attr struct type * \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ +name##_RTEMS_RB_REMOVE(struct name *head, struct type *elm) \ { \ struct type *child, *old, *parent, *right; \ int color; \ \ old = elm; \ - parent = RB_PARENT(elm, field); \ - right = RB_RIGHT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (RB_LEFT(elm, field) == NULL) \ + parent = RTEMS_RB_PARENT(elm, field); \ + right = RTEMS_RB_RIGHT(elm, field); \ + color = RTEMS_RB_COLOR(elm, field); \ + if (RTEMS_RB_LEFT(elm, field) == NULL) \ elm = child = right; \ else if (right == NULL) \ - elm = child = RB_LEFT(elm, field); \ + elm = child = RTEMS_RB_LEFT(elm, field); \ else { \ - if ((child = RB_LEFT(right, field)) == NULL) { \ - child = RB_RIGHT(right, field); \ - RB_RIGHT(old, field) = child; \ + if ((child = RTEMS_RB_LEFT(right, field)) == NULL) { \ + child = RTEMS_RB_RIGHT(right, field); \ + RTEMS_RB_RIGHT(old, field) = child; \ parent = elm = right; \ } else { \ do \ elm = child; \ - while ((child = RB_LEFT(elm, field)) != NULL); \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - RB_LEFT(parent, field) = child; \ - RB_SET_PARENT(RB_RIGHT(old, field), elm, field); \ + while ((child = RTEMS_RB_LEFT(elm, field)) != NULL); \ + child = RTEMS_RB_RIGHT(elm, field); \ + parent = RTEMS_RB_PARENT(elm, field); \ + RTEMS_RB_LEFT(parent, field) = child; \ + RTEMS_RB_SET_PARENT(RTEMS_RB_RIGHT(old, field), elm, field); \ } \ - RB_SET_PARENT(RB_LEFT(old, field), elm, field); \ - color = RB_COLOR(elm, field); \ + RTEMS_RB_SET_PARENT(RTEMS_RB_LEFT(old, field), elm, field); \ + color = RTEMS_RB_COLOR(elm, field); \ elm->field = old->field; \ } \ - RB_SWAP_CHILD(head, old, elm, field); \ + RTEMS_RB_SWAP_CHILD(head, old, elm, field); \ if (child != NULL) { \ - RB_SET_PARENT(child, parent, field); \ - RB_COLOR(child, field) = RB_BLACK; \ - } else if (color != RB_RED && parent != NULL) \ - name##_RB_REMOVE_COLOR(head, parent); \ + RTEMS_RB_SET_PARENT(child, parent, field); \ + RTEMS_RB_COLOR(child, field) = RTEMS_RB_BLACK; \ + } else if (color != RTEMS_RB_RED && parent != NULL) \ + name##_RTEMS_RB_REMOVE_COLOR(head, parent); \ while (parent != NULL) { \ - RB_AUGMENT(parent); \ - parent = RB_PARENT(parent, field); \ + RTEMS_RB_AUGMENT(parent); \ + parent = RTEMS_RB_PARENT(parent, field); \ } \ return (old); \ } -#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \ +#define RTEMS_RB_GENERATE_INSERT(name, type, field, cmp, attr) \ /* Inserts a node into the RB tree */ \ attr struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ +name##_RTEMS_RB_INSERT(struct name *head, struct type *elm) \ { \ struct type *tmp; \ struct type *parent = NULL; \ int comp = 0; \ - tmp = RB_ROOT(head); \ + tmp = RTEMS_RB_ROOT(head); \ while (tmp) { \ parent = tmp; \ comp = (cmp)(elm, parent); \ if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ + tmp = RTEMS_RB_LEFT(tmp, field); \ else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ + tmp = RTEMS_RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ - RB_SET(elm, parent, field); \ + RTEMS_RB_SET(elm, parent, field); \ if (parent != NULL) { \ if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ + RTEMS_RB_LEFT(parent, field) = elm; \ else \ - RB_RIGHT(parent, field) = elm; \ + RTEMS_RB_RIGHT(parent, field) = elm; \ } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ + RTEMS_RB_ROOT(head) = elm; \ + name##_RTEMS_RB_INSERT_COLOR(head, elm); \ while (elm != NULL) { \ - RB_AUGMENT(elm); \ - elm = RB_PARENT(elm, field); \ + RTEMS_RB_AUGMENT(elm); \ + elm = RTEMS_RB_PARENT(elm, field); \ } \ return (NULL); \ } -#define RB_GENERATE_FIND(name, type, field, cmp, attr) \ +#define RTEMS_RB_GENERATE_FIND(name, type, field, cmp, attr) \ /* Finds the node with the same key as elm */ \ attr struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ +name##_RTEMS_RB_FIND(struct name *head, struct type *elm) \ { \ - struct type *tmp = RB_ROOT(head); \ + struct type *tmp = RTEMS_RB_ROOT(head); \ int comp; \ while (tmp) { \ comp = cmp(elm, tmp); \ if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ + tmp = RTEMS_RB_LEFT(tmp, field); \ else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ + tmp = RTEMS_RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ return (NULL); \ } -#define RB_GENERATE_NFIND(name, type, field, cmp, attr) \ +#define RTEMS_RB_GENERATE_NFIND(name, type, field, cmp, attr) \ /* Finds the first node greater than or equal to the search key */ \ attr struct type * \ -name##_RB_NFIND(struct name *head, struct type *elm) \ +name##_RTEMS_RB_NFIND(struct name *head, struct type *elm) \ { \ - struct type *tmp = RB_ROOT(head); \ + struct type *tmp = RTEMS_RB_ROOT(head); \ struct type *res = NULL; \ int comp; \ while (tmp) { \ comp = cmp(elm, tmp); \ if (comp < 0) { \ res = tmp; \ - tmp = RB_LEFT(tmp, field); \ + tmp = RTEMS_RB_LEFT(tmp, field); \ } \ else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ + tmp = RTEMS_RB_RIGHT(tmp, field); \ else \ return (tmp); \ } \ return (res); \ } -#define RB_GENERATE_NEXT(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_NEXT(name, type, field, attr) \ /* ARGSUSED */ \ attr struct type * \ -name##_RB_NEXT(struct type *elm) \ +name##_RTEMS_RB_NEXT(struct type *elm) \ { \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ + if (RTEMS_RB_RIGHT(elm, field)) { \ + elm = RTEMS_RB_RIGHT(elm, field); \ + while (RTEMS_RB_LEFT(elm, field)) \ + elm = RTEMS_RB_LEFT(elm, field); \ } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ + if (RTEMS_RB_PARENT(elm, field) && \ + (elm == RTEMS_RB_LEFT(RTEMS_RB_PARENT(elm, field), field))) \ + elm = RTEMS_RB_PARENT(elm, field); \ else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ + while (RTEMS_RB_PARENT(elm, field) && \ + (elm == RTEMS_RB_RIGHT(RTEMS_RB_PARENT(elm, field), field)))\ + elm = RTEMS_RB_PARENT(elm, field); \ + elm = RTEMS_RB_PARENT(elm, field); \ } \ } \ return (elm); \ } -#define RB_GENERATE_PREV(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_PREV(name, type, field, attr) \ /* ARGSUSED */ \ attr struct type * \ -name##_RB_PREV(struct type *elm) \ +name##_RTEMS_RB_PREV(struct type *elm) \ { \ - if (RB_LEFT(elm, field)) { \ - elm = RB_LEFT(elm, field); \ - while (RB_RIGHT(elm, field)) \ - elm = RB_RIGHT(elm, field); \ + if (RTEMS_RB_LEFT(elm, field)) { \ + elm = RTEMS_RB_LEFT(elm, field); \ + while (RTEMS_RB_RIGHT(elm, field)) \ + elm = RTEMS_RB_RIGHT(elm, field); \ } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ + if (RTEMS_RB_PARENT(elm, field) && \ + (elm == RTEMS_RB_RIGHT(RTEMS_RB_PARENT(elm, field), field))) \ + elm = RTEMS_RB_PARENT(elm, field); \ else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ + while (RTEMS_RB_PARENT(elm, field) && \ + (elm == RTEMS_RB_LEFT(RTEMS_RB_PARENT(elm, field), field)))\ + elm = RTEMS_RB_PARENT(elm, field); \ + elm = RTEMS_RB_PARENT(elm, field); \ } \ } \ return (elm); \ } -#define RB_GENERATE_MINMAX(name, type, field, attr) \ +#define RTEMS_RB_GENERATE_MINMAX(name, type, field, attr) \ attr struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ +name##_RTEMS_RB_MINMAX(struct name *head, int val) \ { \ - struct type *tmp = RB_ROOT(head); \ + struct type *tmp = RTEMS_RB_ROOT(head); \ struct type *parent = NULL; \ while (tmp) { \ parent = tmp; \ if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ + tmp = RTEMS_RB_LEFT(tmp, field); \ else \ - tmp = RB_RIGHT(tmp, field); \ + tmp = RTEMS_RB_RIGHT(tmp, field); \ } \ return (parent); \ } -#define RB_GENERATE_REINSERT(name, type, field, cmp, attr) \ +#define RTEMS_RB_GENERATE_REINSERT(name, type, field, cmp, attr) \ attr struct type * \ -name##_RB_REINSERT(struct name *head, struct type *elm) \ +name##_RTEMS_RB_REINSERT(struct name *head, struct type *elm) \ { \ struct type *cmpelm; \ - if (((cmpelm = RB_PREV(name, head, elm)) != NULL && \ + if (((cmpelm = RTEMS_RB_PREV(name, head, elm)) != NULL && \ cmp(cmpelm, elm) >= 0) || \ - ((cmpelm = RB_NEXT(name, head, elm)) != NULL && \ + ((cmpelm = RTEMS_RB_NEXT(name, head, elm)) != NULL && \ cmp(elm, cmpelm) >= 0)) { \ /* XXXLAS: Remove/insert is heavy handed. */ \ - RB_REMOVE(name, head, elm); \ - return (RB_INSERT(name, head, elm)); \ + RTEMS_RB_REMOVE(name, head, elm); \ + return (RTEMS_RB_INSERT(name, head, elm)); \ } \ return (NULL); \ } \ -#define RB_NEGINF -1 -#define RB_INF 1 +#define RTEMS_RB_NEGINF -1 +#define RTEMS_RB_INF 1 -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(y) -#define RB_PREV(name, x, y) name##_RB_PREV(y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) -#define RB_REINSERT(name, x, y) name##_RB_REINSERT(x, y) +#define RTEMS_RB_INSERT(name, x, y) name##_RTEMS_RB_INSERT(x, y) +#define RTEMS_RB_REMOVE(name, x, y) name##_RTEMS_RB_REMOVE(x, y) +#define RTEMS_RB_FIND(name, x, y) name##_RTEMS_RB_FIND(x, y) +#define RTEMS_RB_NFIND(name, x, y) name##_RTEMS_RB_NFIND(x, y) +#define RTEMS_RB_NEXT(name, x, y) name##_RTEMS_RB_NEXT(y) +#define RTEMS_RB_PREV(name, x, y) name##_RTEMS_RB_PREV(y) +#define RTEMS_RB_MIN(name, x) name##_RTEMS_RB_MINMAX(x, RTEMS_RB_NEGINF) +#define RTEMS_RB_MAX(name, x) name##_RTEMS_RB_MINMAX(x, RTEMS_RB_INF) +#define RTEMS_RB_REINSERT(name, x, y) name##_RTEMS_RB_REINSERT(x, y) -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ +#define RTEMS_RB_FOREACH(x, name, head) \ + for ((x) = RTEMS_RB_MIN(name, head); \ (x) != NULL; \ - (x) = name##_RB_NEXT(x)) + (x) = name##_RTEMS_RB_NEXT(x)) -#define RB_FOREACH_FROM(x, name, y) \ +#define RTEMS_RB_FOREACH_FROM(x, name, y) \ for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + ((x) != NULL) && ((y) = name##_RTEMS_RB_NEXT(x), (x) != NULL); \ (x) = (y)) -#define RB_FOREACH_SAFE(x, name, head, y) \ - for ((x) = RB_MIN(name, head); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ +#define RTEMS_RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RTEMS_RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RTEMS_RB_NEXT(x), (x) != NULL); \ (x) = (y)) -#define RB_FOREACH_REVERSE(x, name, head) \ - for ((x) = RB_MAX(name, head); \ +#define RTEMS_RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RTEMS_RB_MAX(name, head); \ (x) != NULL; \ - (x) = name##_RB_PREV(x)) + (x) = name##_RTEMS_RB_PREV(x)) -#define RB_FOREACH_REVERSE_FROM(x, name, y) \ +#define RTEMS_RB_FOREACH_REVERSE_FROM(x, name, y) \ for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + ((x) != NULL) && ((y) = name##_RTEMS_RB_PREV(x), (x) != NULL); \ (x) = (y)) -#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ - for ((x) = RB_MAX(name, head); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ +#define RTEMS_RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RTEMS_RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RTEMS_RB_PREV(x), (x) != NULL); \ (x) = (y)) #endif /* _RTEMS_SCORE_BSD_TREE_H_ */ diff --git a/cpukit/include/rtems/score/rbtree.h b/cpukit/include/rtems/score/rbtree.h index 04d733ea50..01d886600c 100644 --- a/cpukit/include/rtems/score/rbtree.h +++ b/cpukit/include/rtems/score/rbtree.h @@ -71,7 +71,7 @@ struct RBTree_Control; * tree. */ typedef struct RBTree_Node { - RB_ENTRY(RBTree_Node) Node; + RTEMS_RB_ENTRY(RBTree_Node) Node; } RBTree_Node; /** @@ -80,13 +80,13 @@ typedef struct RBTree_Node { * This is used to manage a red-black tree. A red-black tree consists of a * tree of zero or more nodes. */ -typedef RB_HEAD(RBTree_Control, RBTree_Node) RBTree_Control; +typedef RTEMS_RB_HEAD(RBTree_Control, RBTree_Node) RBTree_Control; /** * @brief Initializer for an empty red-black tree with designator @a name. */ #define RBTREE_INITIALIZER_EMPTY( name ) \ - RB_INITIALIZER( name ) + RTEMS_RB_INITIALIZER( name ) /** * @brief Definition for an empty red-black tree with designator @a name. @@ -105,7 +105,7 @@ typedef RB_HEAD(RBTree_Control, RBTree_Node) RBTree_Control; */ static inline void _RBTree_Set_off_tree( RBTree_Node *the_node ) { - RB_COLOR( the_node, Node ) = -1; + RTEMS_RB_COLOR( the_node, Node ) = -1; } /** @@ -122,7 +122,7 @@ static inline bool _RBTree_Is_node_off_tree( const RBTree_Node *the_node ) { - return RB_COLOR( the_node, Node ) == -1; + return RTEMS_RB_COLOR( the_node, Node ) == -1; } /** @@ -167,7 +167,7 @@ static inline void _RBTree_Add_child( ) { _Assert( _RBTree_Is_node_off_tree( child ) ); - RB_SET( child, parent, Node ); + RTEMS_RB_SET( child, parent, Node ); *link = child; } @@ -265,7 +265,7 @@ static inline RBTree_Node *_RBTree_Root( const RBTree_Control *the_rbtree ) { - return RB_ROOT( the_rbtree ); + return RTEMS_RB_ROOT( the_rbtree ); } /** @@ -280,7 +280,7 @@ static inline RBTree_Node **_RBTree_Root_reference( RBTree_Control *the_rbtree ) { - return &RB_ROOT( the_rbtree ); + return &RTEMS_RB_ROOT( the_rbtree ); } /** @@ -295,7 +295,7 @@ static inline RBTree_Node * const *_RBTree_Root_const_reference( const RBTree_Control *the_rbtree ) { - return &RB_ROOT( the_rbtree ); + return &RTEMS_RB_ROOT( the_rbtree ); } /** @@ -314,7 +314,7 @@ static inline RBTree_Node *_RBTree_Parent( const RBTree_Node *the_node ) { - return RB_PARENT( the_node, Node ); + return RTEMS_RB_PARENT( the_node, Node ); } /** @@ -330,7 +330,7 @@ static inline RBTree_Node *_RBTree_Left( const RBTree_Node *the_node ) { - return RB_LEFT( the_node, Node ); + return RTEMS_RB_LEFT( the_node, Node ); } /** @@ -345,7 +345,7 @@ static inline RBTree_Node **_RBTree_Left_reference( RBTree_Node *the_node ) { - return &RB_LEFT( the_node, Node ); + return &RTEMS_RB_LEFT( the_node, Node ); } /** @@ -361,7 +361,7 @@ static inline RBTree_Node *_RBTree_Right( const RBTree_Node *the_node ) { - return RB_RIGHT( the_node, Node ); + return RTEMS_RB_RIGHT( the_node, Node ); } /** @@ -376,7 +376,7 @@ static inline RBTree_Node **_RBTree_Right_reference( RBTree_Node *the_node ) { - return &RB_RIGHT( the_node, Node ); + return &RTEMS_RB_RIGHT( the_node, Node ); } /** @@ -394,7 +394,7 @@ static inline bool _RBTree_Is_empty( const RBTree_Control *the_rbtree ) { - return RB_EMPTY( the_rbtree ); + return RTEMS_RB_EMPTY( the_rbtree ); } /** @@ -429,7 +429,7 @@ static inline void _RBTree_Initialize_empty( RBTree_Control *the_rbtree ) { - RB_INIT( the_rbtree ); + RTEMS_RB_INIT( the_rbtree ); } /** @@ -445,11 +445,11 @@ static inline void _RBTree_Initialize_one( ) { _Assert( _RBTree_Is_node_off_tree( the_node ) ); - RB_ROOT( the_rbtree ) = the_node; - RB_PARENT( the_node, Node ) = NULL; - RB_LEFT( the_node, Node ) = NULL; - RB_RIGHT( the_node, Node ) = NULL; - RB_COLOR( the_node, Node ) = RB_BLACK; + RTEMS_RB_ROOT( the_rbtree ) = the_node; + RTEMS_RB_PARENT( the_node, Node ) = NULL; + RTEMS_RB_LEFT( the_node, Node ) = NULL; + RTEMS_RB_RIGHT( the_node, Node ) = NULL; + RTEMS_RB_COLOR( the_node, Node ) = RTEMS_RB_BLACK; } /** diff --git a/cpukit/include/rtems/score/watchdogimpl.h b/cpukit/include/rtems/score/watchdogimpl.h index df479aeeed..79fef6f38d 100644 --- a/cpukit/include/rtems/score/watchdogimpl.h +++ b/cpukit/include/rtems/score/watchdogimpl.h @@ -161,13 +161,13 @@ void _Watchdog_Tick( struct Per_CPU_Control *cpu ); * * @param the_watchdog The watchdog to get the state of. * - * @return The RB_COLOR of @a the_watchdog. + * @return The RTEMS_RB_COLOR of @a the_watchdog. */ static inline Watchdog_State _Watchdog_Get_state( const Watchdog_Control *the_watchdog ) { - return (Watchdog_State) RB_COLOR( &the_watchdog->Node.RBTree, Node ); + return (Watchdog_State) RTEMS_RB_COLOR( &the_watchdog->Node.RBTree, Node ); } /** @@ -181,7 +181,7 @@ static inline void _Watchdog_Set_state( Watchdog_State state ) { - RB_COLOR( &the_watchdog->Node.RBTree, Node ) = state; + RTEMS_RB_COLOR( &the_watchdog->Node.RBTree, Node ) = state; } /** @@ -408,7 +408,7 @@ static inline void _Watchdog_Next_first( right = _RBTree_Right( &first->Node.RBTree ); if ( right != NULL ) { - _Assert( RB_COLOR( right, Node ) == RB_RED ); + _Assert( RTEMS_RB_COLOR( right, Node ) == RTEMS_RB_RED ); _Assert( _RBTree_Left( right ) == NULL ); _Assert( _RBTree_Right( right ) == NULL ); header->first = right; diff --git a/cpukit/libfs/src/jffs2/src/fs-rtems.c b/cpukit/libfs/src/jffs2/src/fs-rtems.c index 029cba6618..ab1c88415b 100644 --- a/cpukit/libfs/src/jffs2/src/fs-rtems.c +++ b/cpukit/libfs/src/jffs2/src/fs-rtems.c @@ -1650,7 +1650,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) { /* These must be set manually to preserve other members */ f->highest_version = 0; - f->fragtree = RB_ROOT; + f->fragtree = RTEMS_RB_ROOT; f->metadata = NULL; f->dents = NULL; f->target = NULL; diff --git a/cpukit/libfs/src/jffs2/src/readinode.c b/cpukit/libfs/src/jffs2/src/readinode.c index 9f554f8644..c0b506e1ad 100644 --- a/cpukit/libfs/src/jffs2/src/readinode.c +++ b/cpukit/libfs/src/jffs2/src/readinode.c @@ -474,7 +474,7 @@ static int jffs2_build_inode_fragtree(struct jffs2_sb_info *c, struct jffs2_readinode_info *rii) { struct jffs2_tmp_dnode_info *pen, *last, *this; - struct rb_root ver_root = RB_ROOT; + struct rb_root ver_root = RTEMS_RB_ROOT; uint32_t high_ver = 0; if (rii->mdata_tn) { @@ -571,7 +571,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) jffs2_free_tmp_dnode_info(tn); } - *list = RB_ROOT; + *list = RTEMS_RB_ROOT; } static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) @@ -1336,7 +1336,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, /* OK. We're happy */ f->metadata = frag_first(&f->fragtree)->node; jffs2_free_node_frag(frag_first(&f->fragtree)); - f->fragtree = RB_ROOT; + f->fragtree = RTEMS_RB_ROOT; break; } if (f->inocache->state == INO_STATE_READING) diff --git a/cpukit/score/src/rbtreeextract.c b/cpukit/score/src/rbtreeextract.c index b483226d1e..18676fc10f 100644 --- a/cpukit/score/src/rbtreeextract.c +++ b/cpukit/score/src/rbtreeextract.c @@ -40,9 +40,9 @@ #include -RB_GENERATE_REMOVE_COLOR( RBTree_Control, RBTree_Node, Node, static ) +RTEMS_RB_GENERATE_REMOVE_COLOR( RBTree_Control, RBTree_Node, Node, static ) -RB_GENERATE_REMOVE( RBTree_Control, RBTree_Node, Node, static ) +RTEMS_RB_GENERATE_REMOVE( RBTree_Control, RBTree_Node, Node, static ) #if defined(RTEMS_DEBUG) static const RBTree_Node *_RBTree_Find_root( const RBTree_Node *the_node ) @@ -66,6 +66,6 @@ void _RBTree_Extract( ) { _Assert( _RBTree_Find_root( the_node ) == _RBTree_Root( the_rbtree ) ); - RB_REMOVE( RBTree_Control, the_rbtree, the_node ); + RTEMS_RB_REMOVE( RBTree_Control, the_rbtree, the_node ); _RBTree_Initialize_node( the_node ); } diff --git a/cpukit/score/src/rbtreeinsert.c b/cpukit/score/src/rbtreeinsert.c index 9bebb9be85..0c4a2c8b73 100644 --- a/cpukit/score/src/rbtreeinsert.c +++ b/cpukit/score/src/rbtreeinsert.c @@ -40,12 +40,17 @@ #include -RB_GENERATE_INSERT_COLOR( RBTree_Control, RBTree_Node, Node, static inline ) +RTEMS_RB_GENERATE_INSERT_COLOR( + RBTree_Control, + RBTree_Node, + Node, + static inline +) void _RBTree_Insert_color( RBTree_Control *the_rbtree, RBTree_Node *the_node ) { - RBTree_Control_RB_INSERT_COLOR( the_rbtree, the_node ); + RBTree_Control_RTEMS_RB_INSERT_COLOR( the_rbtree, the_node ); } diff --git a/cpukit/score/src/rbtreenext.c b/cpukit/score/src/rbtreenext.c index a7314ac095..5fd9c183c6 100644 --- a/cpukit/score/src/rbtreenext.c +++ b/cpukit/score/src/rbtreenext.c @@ -42,9 +42,13 @@ #include #include -RB_GENERATE_NEXT( RBTree_Control, RBTree_Node, Node, static ) +RTEMS_RB_GENERATE_NEXT( RBTree_Control, RBTree_Node, Node, static ) RBTree_Node *_RBTree_Successor( const RBTree_Node *node ) { - return RB_NEXT( RBTree_Control, NULL, RTEMS_DECONST( RBTree_Node *, node ) ); + return RTEMS_RB_NEXT( + RBTree_Control, + NULL, + RTEMS_DECONST( RBTree_Node *, node ) + ); } diff --git a/cpukit/score/src/rbtreeprev.c b/cpukit/score/src/rbtreeprev.c index 9d417a79ff..ca06fc9bc8 100644 --- a/cpukit/score/src/rbtreeprev.c +++ b/cpukit/score/src/rbtreeprev.c @@ -41,9 +41,13 @@ #include #include -RB_GENERATE_PREV( RBTree_Control, RBTree_Node, Node, static inline ) +RTEMS_RB_GENERATE_PREV( RBTree_Control, RBTree_Node, Node, static inline ) RBTree_Node *_RBTree_Predecessor( const RBTree_Node *node ) { - return RB_PREV( RBTree_Control, NULL, RTEMS_DECONST( RBTree_Node *, node ) ); + return RTEMS_RB_PREV( + RBTree_Control, + NULL, + RTEMS_DECONST( RBTree_Node *, node ) + ); } diff --git a/cpukit/score/src/rbtreereplace.c b/cpukit/score/src/rbtreereplace.c index 4a022f5b69..3afe1dc455 100644 --- a/cpukit/score/src/rbtreereplace.c +++ b/cpukit/score/src/rbtreereplace.c @@ -63,12 +63,12 @@ void _RBTree_Replace_node( child = _RBTree_Left( victim ); if ( child != NULL ) { - RB_PARENT( child, Node ) = replacement; + RTEMS_RB_PARENT( child, Node ) = replacement; } child = _RBTree_Right( victim ); if ( child != NULL ) { - RB_PARENT( child, Node ) = replacement; + RTEMS_RB_PARENT( child, Node ) = replacement; } *replacement = *victim; diff --git a/spec/build/testsuites/sptests/grp.yml b/spec/build/testsuites/sptests/grp.yml index dc926872c7..2c9de9a128 100644 --- a/spec/build/testsuites/sptests/grp.yml +++ b/spec/build/testsuites/sptests/grp.yml @@ -450,6 +450,8 @@ links: uid: sptls03 - role: build-dependency uid: sptls04 +- role: build-dependency + uid: sptree01 - role: build-dependency uid: spunlimited01 - role: build-dependency diff --git a/spec/build/testsuites/sptests/sptree01.yml b/spec/build/testsuites/sptests/sptree01.yml new file mode 100644 index 0000000000..4f531380be --- /dev/null +++ b/spec/build/testsuites/sptests/sptree01.yml @@ -0,0 +1,19 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2024 Gedare Bloom +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/sptests/sptree01/init.c +stlib: [] +target: testsuites/sptests/sptree01.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/sptests/sprbtree01/init.c b/testsuites/sptests/sprbtree01/init.c index 1e3cba69d0..e2b32f47ed 100644 --- a/testsuites/sptests/sprbtree01/init.c +++ b/testsuites/sptests/sprbtree01/init.c @@ -80,13 +80,13 @@ typedef struct { static test_node node_array[100]; -#define RED RB_RED +#define RED RTEMS_RB_RED -#define BLACK RB_BLACK +#define BLACK RTEMS_RB_BLACK static int rb_color( const rtems_rbtree_node *n ) { - return RB_COLOR( n, Node ); + return RTEMS_RB_COLOR( n, Node ); } static rtems_rbtree_compare_result test_compare_function ( @@ -1918,9 +1918,9 @@ static void postorder_tree_init( const postorder_node_description *pnd; pnd = &pt->tree[ i ]; - RB_PARENT( TN( i ), Node) = pnd->parent; - RB_LEFT( TN( i ), Node) = pnd->left; - RB_RIGHT( TN( i ), Node) = pnd->right; + RTEMS_RB_PARENT( TN( i ), Node) = pnd->parent; + RTEMS_RB_LEFT( TN( i ), Node) = pnd->left; + RTEMS_RB_RIGHT( TN( i ), Node) = pnd->right; } } diff --git a/testsuites/sptests/sptree01/init.c b/testsuites/sptests/sptree01/init.c new file mode 100644 index 0000000000..52114f6769 --- /dev/null +++ b/testsuites/sptests/sptree01/init.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (c) 2024 Gedare Bloom. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include + +#include "sys/tree.h" + +const char rtems_test_name[] = "SPTREE 1"; + +rtems_task Init( rtems_task_argument ignored ) +{ + TEST_BEGIN(); + + TEST_END(); + rtems_test_exit(0); +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE +#define CONFIGURE_MAXIMUM_TASKS 1 + +#define CONFIGURE_INIT +#include + +/* global variables */ diff --git a/testsuites/sptests/sptree01/sptree01.doc b/testsuites/sptests/sptree01/sptree01.doc new file mode 100644 index 0000000000..7087e85c5b --- /dev/null +++ b/testsuites/sptests/sptree01/sptree01.doc @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# COPYRIGHT (c) 1989-2009. +# On-Line Applications Research Corporation (OAR). +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +This file describes the directives and concepts tested by this test set. + +test set name: sptree01 + +directives: + +concepts: + ++ Ensure that namespace for sys/tree.h is clean with rtems. diff --git a/testsuites/sptests/sptree01/sptree01.scn b/testsuites/sptests/sptree01/sptree01.scn new file mode 100644 index 0000000000..98cd157273 --- /dev/null +++ b/testsuites/sptests/sptree01/sptree01.scn @@ -0,0 +1,2 @@ +*** BEGIN OF TEST SPTREE 1 *** +*** END OF TEST SPTREE 1 *** diff --git a/testsuites/sptests/sptree01/sys/tree.h b/testsuites/sptests/sptree01/sys/tree.h new file mode 100644 index 0000000000..c11bccfb38 --- /dev/null +++ b/testsuites/sptests/sptree01/sys/tree.h @@ -0,0 +1,1062 @@ +/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ +/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ + +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _SYS_TREE_H_ +#define _SYS_TREE_H_ + +#include + +/* + * This file defines data structures for different types of trees: + * splay trees and rank-balanced trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A rank-balanced tree is a binary search tree with an integer + * rank-difference as an attribute of each pointer from parent to child. + * The sum of the rank-differences on any path from a node down to null is + * the same, and defines the rank of that node. The rank of the null node + * is -1. + * + * Different additional conditions define different sorts of balanced trees, + * including "red-black" and "AVL" trees. The set of conditions applied here + * are the "weak-AVL" conditions of Haeupler, Sen and Tarjan presented in in + * "Rank Balanced Trees", ACM Transactions on Algorithms Volume 11 Issue 4 June + * 2015 Article No.: 30pp 1–26 https://doi.org/10.1145/2689412 (the HST paper): + * - every rank-difference is 1 or 2. + * - the rank of any leaf is 1. + * + * For historical reasons, rank differences that are even are associated + * with the color red (Rank-Even-Difference), and the child that a red edge + * points to is called a red child. + * + * Every operation on a rank-balanced tree is bounded as O(lg n). + * The maximum height of a rank-balanced tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __unused __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __unused __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __unused __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + __typeof(cmp(NULL, NULL)) __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if (__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + __typeof(cmp(NULL, NULL)) __comp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ +\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ + __left = __right = &__node; \ +\ + while (1) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a rank-balanced tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_link[3]; \ +} + +/* + * With the expectation that any object of struct type has an + * address that is a multiple of 4, and that therefore the + * 2 least significant bits of a pointer to struct type are + * always zero, this implementation sets those bits to indicate + * that the left or right child of the tree node is "red". + */ +#define _RB_LINK(elm, dir, field) (elm)->field.rbe_link[dir] +#define _RB_UP(elm, field) _RB_LINK(elm, 0, field) +#define _RB_L ((__uintptr_t)1) +#define _RB_R ((__uintptr_t)2) +#define _RB_LR ((__uintptr_t)3) +#define _RB_BITS(elm) (*(__uintptr_t *)&elm) +#define _RB_BITSUP(elm, field) _RB_BITS(_RB_UP(elm, field)) +#define _RB_PTR(elm) (__typeof(elm)) \ + ((__uintptr_t)elm & ~_RB_LR) + +#define RB_PARENT(elm, field) _RB_PTR(_RB_UP(elm, field)) +#define RB_LEFT(elm, field) _RB_LINK(elm, _RB_L, field) +#define RB_RIGHT(elm, field) _RB_LINK(elm, _RB_R, field) +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET_PARENT(dst, src, field) do { \ + _RB_BITSUP(dst, field) = (__uintptr_t)src | \ + (_RB_BITSUP(dst, field) & _RB_LR); \ +} while (/*CONSTCOND*/ 0) + +#define RB_SET(elm, parent, field) do { \ + _RB_UP(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ +} while (/*CONSTCOND*/ 0) + +/* + * Either RB_AUGMENT or RB_AUGMENT_CHECK is invoked in a loop at the root of + * every modified subtree, from the bottom up to the root, to update augmented + * node data. RB_AUGMENT_CHECK returns true only when the update changes the + * node data, so that updating can be stopped short of the root when it returns + * false. + */ +#ifndef RB_AUGMENT_CHECK +#ifndef RB_AUGMENT +#define RB_AUGMENT_CHECK(x) 0 +#else +#define RB_AUGMENT_CHECK(x) (RB_AUGMENT(x), 1) +#endif +#endif + +#define RB_UPDATE_AUGMENT(elm, field) do { \ + __typeof(elm) rb_update_tmp = (elm); \ + while (RB_AUGMENT_CHECK(rb_update_tmp) && \ + (rb_update_tmp = RB_PARENT(rb_update_tmp, field)) != NULL) \ + ; \ +} while (0) + +#define RB_SWAP_CHILD(head, par, out, in, field) do { \ + if (par == NULL) \ + RB_ROOT(head) = (in); \ + else if ((out) == RB_LEFT(par, field)) \ + RB_LEFT(par, field) = (in); \ + else \ + RB_RIGHT(par, field) = (in); \ +} while (/*CONSTCOND*/ 0) + +/* + * RB_ROTATE macro partially restructures the tree to improve balance. In the + * case when dir is _RB_L, tmp is a right child of elm. After rotation, elm + * is a left child of tmp, and the subtree that represented the items between + * them, which formerly hung to the left of tmp now hangs to the right of elm. + * The parent-child relationship between elm and its former parent is not + * changed; where this macro once updated those fields, that is now left to the + * caller of RB_ROTATE to clean up, so that a pair of rotations does not twice + * update the same pair of pointer fields with distinct values. + */ +#define RB_ROTATE(elm, tmp, dir, field) do { \ + if ((_RB_LINK(elm, dir ^ _RB_LR, field) = \ + _RB_LINK(tmp, dir, field)) != NULL) \ + RB_SET_PARENT(_RB_LINK(tmp, dir, field), elm, field); \ + _RB_LINK(tmp, dir, field) = (elm); \ + RB_SET_PARENT(elm, tmp, field); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ + RB_PROTOTYPE_RANK(name, type, attr) \ + RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \ + RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \ + RB_PROTOTYPE_INSERT_FINISH(name, type, attr); \ + RB_PROTOTYPE_INSERT(name, type, attr); \ + RB_PROTOTYPE_REMOVE(name, type, attr); \ + RB_PROTOTYPE_FIND(name, type, attr); \ + RB_PROTOTYPE_NFIND(name, type, attr); \ + RB_PROTOTYPE_NEXT(name, type, attr); \ + RB_PROTOTYPE_INSERT_NEXT(name, type, attr); \ + RB_PROTOTYPE_PREV(name, type, attr); \ + RB_PROTOTYPE_INSERT_PREV(name, type, attr); \ + RB_PROTOTYPE_MINMAX(name, type, attr); \ + RB_PROTOTYPE_REINSERT(name, type, attr); +#ifdef _RB_DIAGNOSTIC +#define RB_PROTOTYPE_RANK(name, type, attr) \ + attr int name##_RB_RANK(struct type *); +#else +#define RB_PROTOTYPE_RANK(name, type, attr) +#endif +#define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \ + attr struct type *name##_RB_INSERT_COLOR(struct name *, \ + struct type *, struct type *) +#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \ + attr struct type *name##_RB_REMOVE_COLOR(struct name *, \ + struct type *, struct type *) +#define RB_PROTOTYPE_REMOVE(name, type, attr) \ + attr struct type *name##_RB_REMOVE(struct name *, struct type *) +#define RB_PROTOTYPE_INSERT_FINISH(name, type, attr) \ + attr struct type *name##_RB_INSERT_FINISH(struct name *, \ + struct type *, struct type **, struct type *) +#define RB_PROTOTYPE_INSERT(name, type, attr) \ + attr struct type *name##_RB_INSERT(struct name *, struct type *) +#define RB_PROTOTYPE_FIND(name, type, attr) \ + attr struct type *name##_RB_FIND(struct name *, struct type *) +#define RB_PROTOTYPE_NFIND(name, type, attr) \ + attr struct type *name##_RB_NFIND(struct name *, struct type *) +#define RB_PROTOTYPE_NEXT(name, type, attr) \ + attr struct type *name##_RB_NEXT(struct type *) +#define RB_PROTOTYPE_INSERT_NEXT(name, type, attr) \ + attr struct type *name##_RB_INSERT_NEXT(struct name *, \ + struct type *, struct type *) +#define RB_PROTOTYPE_PREV(name, type, attr) \ + attr struct type *name##_RB_PREV(struct type *) +#define RB_PROTOTYPE_INSERT_PREV(name, type, attr) \ + attr struct type *name##_RB_INSERT_PREV(struct name *, \ + struct type *, struct type *) +#define RB_PROTOTYPE_MINMAX(name, type, attr) \ + attr struct type *name##_RB_MINMAX(struct name *, int) +#define RB_PROTOTYPE_REINSERT(name, type, attr) \ + attr struct type *name##_RB_REINSERT(struct name *, struct type *) + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ + RB_GENERATE_RANK(name, type, field, attr) \ + RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ + RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ + RB_GENERATE_INSERT_FINISH(name, type, field, attr) \ + RB_GENERATE_INSERT(name, type, field, cmp, attr) \ + RB_GENERATE_REMOVE(name, type, field, attr) \ + RB_GENERATE_FIND(name, type, field, cmp, attr) \ + RB_GENERATE_NFIND(name, type, field, cmp, attr) \ + RB_GENERATE_NEXT(name, type, field, attr) \ + RB_GENERATE_INSERT_NEXT(name, type, field, cmp, attr) \ + RB_GENERATE_PREV(name, type, field, attr) \ + RB_GENERATE_INSERT_PREV(name, type, field, cmp, attr) \ + RB_GENERATE_MINMAX(name, type, field, attr) \ + RB_GENERATE_REINSERT(name, type, field, cmp, attr) + +#ifdef _RB_DIAGNOSTIC +#ifndef RB_AUGMENT +#define _RB_AUGMENT_VERIFY(x) RB_AUGMENT_CHECK(x) +#else +#define _RB_AUGMENT_VERIFY(x) 0 +#endif +#define RB_GENERATE_RANK(name, type, field, attr) \ +/* \ + * Return the rank of the subtree rooted at elm, or -1 if the subtree \ + * is not rank-balanced, or has inconsistent augmentation data. + */ \ +attr int \ +name##_RB_RANK(struct type *elm) \ +{ \ + struct type *left, *right, *up; \ + int left_rank, right_rank; \ + \ + if (elm == NULL) \ + return (0); \ + up = _RB_UP(elm, field); \ + left = RB_LEFT(elm, field); \ + left_rank = ((_RB_BITS(up) & _RB_L) ? 2 : 1) + \ + name##_RB_RANK(left); \ + right = RB_RIGHT(elm, field); \ + right_rank = ((_RB_BITS(up) & _RB_R) ? 2 : 1) + \ + name##_RB_RANK(right); \ + if (left_rank != right_rank || \ + (left_rank == 2 && left == NULL && right == NULL) || \ + _RB_AUGMENT_VERIFY(elm)) \ + return (-1); \ + return (left_rank); \ +} +#else +#define RB_GENERATE_RANK(name, type, field, attr) +#endif + +#define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ +attr struct type * \ +name##_RB_INSERT_COLOR(struct name *head, \ + struct type *parent, struct type *elm) \ +{ \ + /* \ + * Initially, elm is a leaf. Either its parent was previously \ + * a leaf, with two black null children, or an interior node \ + * with a black non-null child and a red null child. The \ + * balance criterion "the rank of any leaf is 1" precludes the \ + * possibility of two red null children for the initial parent. \ + * So the first loop iteration cannot lead to accessing an \ + * uninitialized 'child', and a later iteration can only happen \ + * when a value has been assigned to 'child' in the previous \ + * one. \ + */ \ + struct type *child, *child_up, *gpar; \ + __uintptr_t elmdir, sibdir; \ + \ + do { \ + /* the rank of the tree rooted at elm grew */ \ + gpar = _RB_UP(parent, field); \ + elmdir = RB_RIGHT(parent, field) == elm ? _RB_R : _RB_L; \ + if (_RB_BITS(gpar) & elmdir) { \ + /* shorten the parent-elm edge to rebalance */ \ + _RB_BITSUP(parent, field) ^= elmdir; \ + return (NULL); \ + } \ + sibdir = elmdir ^ _RB_LR; \ + /* the other edge must change length */ \ + _RB_BITSUP(parent, field) ^= sibdir; \ + if ((_RB_BITS(gpar) & _RB_LR) == 0) { \ + /* both edges now short, retry from parent */ \ + child = elm; \ + elm = parent; \ + continue; \ + } \ + _RB_UP(parent, field) = gpar = _RB_PTR(gpar); \ + if (_RB_BITSUP(elm, field) & elmdir) { \ + /* \ + * Exactly one of the edges descending from elm \ + * is long. The long one is in the same \ + * direction as the edge from parent to elm, \ + * so change that by rotation. The edge from \ + * parent to z was shortened above. Shorten \ + * the long edge down from elm, and adjust \ + * other edge lengths based on the downward \ + * edges from 'child'. \ + * \ + * par par \ + * / \ / \ \ + * elm z / z \ + * / \ child \ + * / child / \ \ + * / / \ elm \ \ + * w / \ / \ y \ + * x y w \ \ + * x \ + */ \ + RB_ROTATE(elm, child, elmdir, field); \ + child_up = _RB_UP(child, field); \ + if (_RB_BITS(child_up) & sibdir) \ + _RB_BITSUP(parent, field) ^= elmdir; \ + if (_RB_BITS(child_up) & elmdir) \ + _RB_BITSUP(elm, field) ^= _RB_LR; \ + else \ + _RB_BITSUP(elm, field) ^= elmdir; \ + /* if child is a leaf, don't augment elm, \ + * since it is restored to be a leaf again. */ \ + if ((_RB_BITS(child_up) & _RB_LR) == 0) \ + elm = child; \ + } else \ + child = elm; \ + \ + /* \ + * The long edge descending from 'child' points back \ + * in the direction of 'parent'. Rotate to make \ + * 'parent' a child of 'child', then make both edges \ + * of 'child' short to rebalance. \ + * \ + * par child \ + * / \ / \ \ + * / z x par \ + * child / \ \ + * / \ / z \ + * x \ y \ + * y \ + */ \ + RB_ROTATE(parent, child, sibdir, field); \ + _RB_UP(child, field) = gpar; \ + RB_SWAP_CHILD(head, gpar, parent, child, field); \ + /* \ + * Elements rotated down have new, smaller subtrees, \ + * so update augmentation for them. \ + */ \ + if (elm != child) \ + (void)RB_AUGMENT_CHECK(elm); \ + (void)RB_AUGMENT_CHECK(parent); \ + return (child); \ + } while ((parent = gpar) != NULL); \ + return (NULL); \ +} + +#ifndef RB_STRICT_HST +/* + * In REMOVE_COLOR, the HST paper, in figure 3, in the single-rotate case, has + * 'parent' with one higher rank, and then reduces its rank if 'parent' has + * become a leaf. This implementation always has the parent in its new position + * with lower rank, to avoid the leaf check. Define RB_STRICT_HST to 1 to get + * the behavior that HST describes. + */ +#define RB_STRICT_HST 0 +#endif + +#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ +attr struct type * \ +name##_RB_REMOVE_COLOR(struct name *head, \ + struct type *parent, struct type *elm) \ +{ \ + struct type *gpar, *sib, *up; \ + __uintptr_t elmdir, sibdir; \ + \ + if (RB_RIGHT(parent, field) == elm && \ + RB_LEFT(parent, field) == elm) { \ + /* Deleting a leaf that is an only-child creates a \ + * rank-2 leaf. Demote that leaf. */ \ + _RB_UP(parent, field) = _RB_PTR(_RB_UP(parent, field)); \ + elm = parent; \ + if ((parent = _RB_UP(elm, field)) == NULL) \ + return (NULL); \ + } \ + do { \ + /* the rank of the tree rooted at elm shrank */ \ + gpar = _RB_UP(parent, field); \ + elmdir = RB_RIGHT(parent, field) == elm ? _RB_R : _RB_L; \ + _RB_BITS(gpar) ^= elmdir; \ + if (_RB_BITS(gpar) & elmdir) { \ + /* lengthen the parent-elm edge to rebalance */ \ + _RB_UP(parent, field) = gpar; \ + return (NULL); \ + } \ + if (_RB_BITS(gpar) & _RB_LR) { \ + /* shorten other edge, retry from parent */ \ + _RB_BITS(gpar) ^= _RB_LR; \ + _RB_UP(parent, field) = gpar; \ + gpar = _RB_PTR(gpar); \ + continue; \ + } \ + sibdir = elmdir ^ _RB_LR; \ + sib = _RB_LINK(parent, sibdir, field); \ + up = _RB_UP(sib, field); \ + _RB_BITS(up) ^= _RB_LR; \ + if ((_RB_BITS(up) & _RB_LR) == 0) { \ + /* shorten edges descending from sib, retry */ \ + _RB_UP(sib, field) = up; \ + continue; \ + } \ + if ((_RB_BITS(up) & sibdir) == 0) { \ + /* \ + * The edge descending from 'sib' away from \ + * 'parent' is long. The short edge descending \ + * from 'sib' toward 'parent' points to 'elm*' \ + * Rotate to make 'sib' a child of 'elm*' \ + * then adjust the lengths of the edges \ + * descending from 'sib' and 'elm*'. \ + * \ + * par par \ + * / \ / \ \ + * / sib elm \ \ + * / / \ elm* \ + * elm elm* \ / \ \ + * / \ \ / \ \ + * / \ z / \ \ + * x y x sib \ + * / \ \ + * / z \ + * y \ + */ \ + elm = _RB_LINK(sib, elmdir, field); \ + /* elm is a 1-child. First rotate at elm. */ \ + RB_ROTATE(sib, elm, sibdir, field); \ + up = _RB_UP(elm, field); \ + _RB_BITSUP(parent, field) ^= \ + (_RB_BITS(up) & elmdir) ? _RB_LR : elmdir; \ + _RB_BITSUP(sib, field) ^= \ + (_RB_BITS(up) & sibdir) ? _RB_LR : sibdir; \ + _RB_BITSUP(elm, field) |= _RB_LR; \ + } else { \ + if ((_RB_BITS(up) & elmdir) == 0 && \ + RB_STRICT_HST && elm != NULL) { \ + /* if parent does not become a leaf, \ + do not demote parent yet. */ \ + _RB_BITSUP(parent, field) ^= sibdir; \ + _RB_BITSUP(sib, field) ^= _RB_LR; \ + } else if ((_RB_BITS(up) & elmdir) == 0) { \ + /* demote parent. */ \ + _RB_BITSUP(parent, field) ^= elmdir; \ + _RB_BITSUP(sib, field) ^= sibdir; \ + } else \ + _RB_BITSUP(sib, field) ^= sibdir; \ + elm = sib; \ + } \ + \ + /* \ + * The edge descending from 'elm' away from 'parent' \ + * is short. Rotate to make 'parent' a child of 'elm', \ + * then lengthen the short edges descending from \ + * 'parent' and 'elm' to rebalance. \ + * \ + * par elm \ + * / \ / \ \ + * e \ / \ \ + * elm / \ \ + * / \ par s \ + * / \ / \ \ + * / \ e \ \ + * x s x \ + */ \ + RB_ROTATE(parent, elm, elmdir, field); \ + RB_SET_PARENT(elm, gpar, field); \ + RB_SWAP_CHILD(head, gpar, parent, elm, field); \ + /* \ + * An element rotated down, but not into the search \ + * path has a new, smaller subtree, so update \ + * augmentation for it. \ + */ \ + if (sib != elm) \ + (void)RB_AUGMENT_CHECK(sib); \ + return (parent); \ + } while (elm = parent, (parent = gpar) != NULL); \ + return (NULL); \ +} + +#define _RB_AUGMENT_WALK(elm, match, field) \ +do { \ + if (match == elm) \ + match = NULL; \ +} while (RB_AUGMENT_CHECK(elm) && \ + (elm = RB_PARENT(elm, field)) != NULL) + +#define RB_GENERATE_REMOVE(name, type, field, attr) \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *out) \ +{ \ + struct type *child, *in, *opar, *parent; \ + \ + child = RB_LEFT(out, field); \ + in = RB_RIGHT(out, field); \ + opar = _RB_UP(out, field); \ + if (in == NULL || child == NULL) { \ + in = child = (in == NULL ? child : in); \ + parent = opar = _RB_PTR(opar); \ + } else { \ + parent = in; \ + while (RB_LEFT(in, field)) \ + in = RB_LEFT(in, field); \ + RB_SET_PARENT(child, in, field); \ + RB_LEFT(in, field) = child; \ + child = RB_RIGHT(in, field); \ + if (parent != in) { \ + RB_SET_PARENT(parent, in, field); \ + RB_RIGHT(in, field) = parent; \ + parent = RB_PARENT(in, field); \ + RB_LEFT(parent, field) = child; \ + } \ + _RB_UP(in, field) = opar; \ + opar = _RB_PTR(opar); \ + } \ + RB_SWAP_CHILD(head, opar, out, in, field); \ + if (child != NULL) \ + _RB_UP(child, field) = parent; \ + if (parent != NULL) { \ + opar = name##_RB_REMOVE_COLOR(head, parent, child); \ + /* if rotation has made 'parent' the root of the same \ + * subtree as before, don't re-augment it. */ \ + if (parent == in && RB_LEFT(parent, field) == NULL) { \ + opar = NULL; \ + parent = RB_PARENT(parent, field); \ + } \ + _RB_AUGMENT_WALK(parent, opar, field); \ + if (opar != NULL) { \ + /* \ + * Elements rotated into the search path have \ + * changed subtrees, so update augmentation for \ + * them if AUGMENT_WALK didn't. \ + */ \ + (void)RB_AUGMENT_CHECK(opar); \ + (void)RB_AUGMENT_CHECK(RB_PARENT(opar, field)); \ + } \ + } \ + return (out); \ +} + +#define RB_GENERATE_INSERT_FINISH(name, type, field, attr) \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT_FINISH(struct name *head, struct type *parent, \ + struct type **pptr, struct type *elm) \ +{ \ + struct type *tmp = NULL; \ + \ + RB_SET(elm, parent, field); \ + *pptr = elm; \ + if (parent != NULL) \ + tmp = name##_RB_INSERT_COLOR(head, parent, elm); \ + _RB_AUGMENT_WALK(elm, tmp, field); \ + if (tmp != NULL) \ + /* \ + * An element rotated into the search path has a \ + * changed subtree, so update augmentation for it if \ + * AUGMENT_WALK didn't. \ + */ \ + (void)RB_AUGMENT_CHECK(tmp); \ + return (NULL); \ +} + +#define RB_GENERATE_INSERT(name, type, field, cmp, attr) \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type **tmpp = &RB_ROOT(head); \ + struct type *parent = NULL; \ + \ + while ((tmp = *tmpp) != NULL) { \ + parent = tmp; \ + __typeof(cmp(NULL, NULL)) comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmpp = &RB_LEFT(parent, field); \ + else if (comp > 0) \ + tmpp = &RB_RIGHT(parent, field); \ + else \ + return (parent); \ + } \ + return (name##_RB_INSERT_FINISH(head, parent, tmpp, elm)); \ +} + +#define RB_GENERATE_FIND(name, type, field, cmp, attr) \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + __typeof(cmp(NULL, NULL)) comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} + +#define RB_GENERATE_NFIND(name, type, field, cmp, attr) \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + __typeof(cmp(NULL, NULL)) comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} + +#define RB_GENERATE_NEXT(name, type, field, attr) \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + return (elm); \ +} + +#if defined(_KERNEL) && defined(DIAGNOSTIC) +#define _RB_ORDER_CHECK(cmp, lo, hi) do { \ + KASSERT((cmp)(lo, hi) < 0, ("out of order insertion")); \ +} while (0) +#else +#define _RB_ORDER_CHECK(cmp, lo, hi) do {} while (0) +#endif + +#define RB_GENERATE_INSERT_NEXT(name, type, field, cmp, attr) \ +/* Inserts a node into the next position in the RB tree */ \ +attr struct type * \ +name##_RB_INSERT_NEXT(struct name *head, \ + struct type *elm, struct type *next) \ +{ \ + struct type *tmp; \ + struct type **tmpp = &RB_RIGHT(elm, field); \ + \ + _RB_ORDER_CHECK(cmp, elm, next); \ + if (name##_RB_NEXT(elm) != NULL) \ + _RB_ORDER_CHECK(cmp, next, name##_RB_NEXT(elm)); \ + while ((tmp = *tmpp) != NULL) { \ + elm = tmp; \ + tmpp = &RB_LEFT(elm, field); \ + } \ + return (name##_RB_INSERT_FINISH(head, elm, tmpp, next)); \ +} + +#define RB_GENERATE_PREV(name, type, field, attr) \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + return (elm); \ +} + +#define RB_GENERATE_INSERT_PREV(name, type, field, cmp, attr) \ +/* Inserts a node into the prev position in the RB tree */ \ +attr struct type * \ +name##_RB_INSERT_PREV(struct name *head, \ + struct type *elm, struct type *prev) \ +{ \ + struct type *tmp; \ + struct type **tmpp = &RB_LEFT(elm, field); \ + \ + _RB_ORDER_CHECK(cmp, prev, elm); \ + if (name##_RB_PREV(elm) != NULL) \ + _RB_ORDER_CHECK(cmp, name##_RB_PREV(elm), prev); \ + while ((tmp = *tmpp) != NULL) { \ + elm = tmp; \ + tmpp = &RB_RIGHT(elm, field); \ + } \ + return (name##_RB_INSERT_FINISH(head, elm, tmpp, prev)); \ +} + +#define RB_GENERATE_MINMAX(name, type, field, attr) \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_GENERATE_REINSERT(name, type, field, cmp, attr) \ +attr struct type * \ +name##_RB_REINSERT(struct name *head, struct type *elm) \ +{ \ + struct type *cmpelm; \ + if (((cmpelm = RB_PREV(name, head, elm)) != NULL && \ + cmp(cmpelm, elm) >= 0) || \ + ((cmpelm = RB_NEXT(name, head, elm)) != NULL && \ + cmp(elm, cmpelm) >= 0)) { \ + /* XXXLAS: Remove/insert is heavy handed. */ \ + RB_REMOVE(name, head, elm); \ + return (RB_INSERT(name, head, elm)); \ + } \ + return (NULL); \ +} \ + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_INSERT_NEXT(name, x, y, z) name##_RB_INSERT_NEXT(x, y, z) +#define RB_INSERT_PREV(name, x, y, z) name##_RB_INSERT_PREV(x, y, z) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) +#define RB_REINSERT(name, x, y) name##_RB_REINSERT(x, y) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#endif /* _SYS_TREE_H_ */