Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151148246
D36484.id110341.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D36484.id110341.diff
View Options
diff --git a/sys/sys/tree.h b/sys/sys/tree.h
--- a/sys/sys/tree.h
+++ b/sys/sys/tree.h
@@ -410,12 +410,17 @@
RB_SET_PARENT(elm, tmp, field); \
} while (/*CONSTCOND*/ 0)
+#if defined(_KERNEL) && defined(DIAGNOSTIC) && !defined(_RB_DIAGNOSTIC)
+#define _RB_DIAGNOSTIC 1
+#endif
+
/* 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(name, type, attr); \
@@ -426,6 +431,12 @@
RB_PROTOTYPE_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 void name##_RB_INSERT_COLOR(struct name *, struct type *)
#define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \
@@ -456,6 +467,7 @@
#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(name, type, field, cmp, attr) \
@@ -467,6 +479,31 @@
RB_GENERATE_MINMAX(name, type, field, attr) \
RB_GENERATE_REINSERT(name, type, field, cmp, attr)
+#ifdef _RB_DIAGNOSTIC
+#define RB_GENERATE_RANK(name, type, field, attr) \
+attr int \
+name##_RB_RANK(struct type *elm) \
+{ \
+ struct type *left, *right; \
+ int left_rank, right_rank; \
+ __uintptr_t bits; \
+ \
+ if (elm == NULL) \
+ return (0); \
+ bits = RB_BITS(elm, field); \
+ left = RB_LEFT(elm, field); \
+ left_rank = ((bits & RB_RED_L) ? 2 : 1) + name##_RB_RANK(left); \
+ right = RB_RIGHT(elm, field); \
+ right_rank = ((bits & RB_RED_R) ? 2 : 1) + name##_RB_RANK(right); \
+ if (left_rank != right_rank || \
+ (left_rank == 2 && left == NULL && right == NULL)) \
+ 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 void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
diff --git a/tests/sys/sys/rb_test.c b/tests/sys/sys/rb_test.c
--- a/tests/sys/sys/rb_test.c
+++ b/tests/sys/sys/rb_test.c
@@ -29,6 +29,7 @@
*/
#include <sys/types.h>
+#define _RB_DIAGNOSTIC 1
#include <sys/tree.h>
#include <stdlib.h>
@@ -54,52 +55,54 @@
RB_GENERATE(tree, node, node, compare);
#define ITER 150
-#define MIN 5
-#define MAX 5000
ATF_TC_WITHOUT_HEAD(rb_test);
ATF_TC_BODY(rb_test, tc)
{
- struct node *tmp, *ins;
- int i, max, min;
+ struct node *tmp, *ins, store[ITER];
+ int i, j, k, max, min;
- max = min = 42; /* pacify gcc */
+ min = ITER;
+ max = -1;
RB_INIT(&root);
+ /* Initialize keys */
+ for (i = 0; i < ITER; i++)
+ store[i].key = i;
+
+ /* Randomly shuffle keys */
+ for (i = 0; i < ITER; i++) {
+ j = i + arc4random_uniform(ITER - i);
+ k = store[j].key;
+ store[j].key = store[i].key;
+ store[i].key = k;
+ }
+
for (i = 0; i < ITER; i++) {
- tmp = malloc(sizeof(struct node));
- ATF_REQUIRE_MSG(tmp != NULL, "malloc failed");
- do {
- tmp->key = arc4random_uniform(MAX-MIN);
- tmp->key += MIN;
- } while (RB_FIND(tree, &root, tmp) != NULL);
- if (i == 0)
- max = min = tmp->key;
- else {
- if (tmp->key > max)
- max = tmp->key;
- if (tmp->key < min)
- min = tmp->key;
+ for (j = 0; j < i; ++j) {
+ tmp = &store[j];
+ ATF_REQUIRE_EQ(tmp, RB_FIND(tree, &root, tmp));
}
+ tmp = &store[i];
+ if (tmp->key > max)
+ max = tmp->key;
+ if (tmp->key < min)
+ min = tmp->key;
ATF_REQUIRE_EQ(NULL, RB_INSERT(tree, &root, tmp));
+ ins = RB_MIN(tree, &root);
+ ATF_REQUIRE_MSG(ins != NULL, "RB_MIN error");
+ ATF_CHECK_EQ(min, ins->key);
+ ins = RB_MAX(tree, &root);
+ ATF_REQUIRE_MSG(ins != NULL, "RB_MAX error");
+ ATF_CHECK_EQ(max, ins->key);
}
-
- ins = RB_MIN(tree, &root);
- ATF_REQUIRE_MSG(ins != NULL, "RB_MIN error");
- ATF_CHECK_EQ(min, ins->key);
- tmp = ins;
- ins = RB_MAX(tree, &root);
- ATF_REQUIRE_MSG(ins != NULL, "RB_MAX error");
- ATF_CHECK_EQ(max, ins->key);
-
- ATF_CHECK_EQ(tmp, RB_REMOVE(tree, &root, tmp));
-
- for (i = 0; i < ITER - 1; i++) {
+ tmp = RB_ROOT(&root);
+ ATF_REQUIRE_MSG(tree_RB_RANK(tmp) >= 0, "RB rank balance error");
+ for (i = 0; i < ITER; i++) {
tmp = RB_ROOT(&root);
ATF_REQUIRE_MSG(tmp != NULL, "RB_ROOT error");
ATF_CHECK_EQ(tmp, RB_REMOVE(tree, &root, tmp));
- free(tmp);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 10:24 AM (1 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31025554
Default Alt Text
D36484.id110341.diff (5 KB)
Attached To
Mode
D36484: rb_tree: test rank balance
Attached
Detach File
Event Timeline
Log In to Comment