summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2016-09-15 06:07:23 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2016-09-15 06:07:23 +0000
commite447b35affbce6deeba06fa2839547dec325797a (patch)
treed00af09937dbab22c07d24a41b9477cd2593f42e /sys
parent9cf4d0680ca98c4e991c6ee31a702857f3f9594d (diff)
add RBT_POISON and RBT_CHECK so you can poison the pointers in RBT_ENTRYs
this seems like a better way forward than simply removing the poisoning that uvm does.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_tree.c20
-rw-r--r--sys/sys/tree.h18
2 files changed, 36 insertions, 2 deletions
diff --git a/sys/kern/subr_tree.c b/sys/kern/subr_tree.c
index 930b94a9dad..89d82588e77 100644
--- a/sys/kern/subr_tree.c
+++ b/sys/kern/subr_tree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_tree.c,v 1.3 2016/09/15 05:31:24 dlg Exp $ */
+/* $OpenBSD: subr_tree.c,v 1.4 2016/09/15 06:07:22 dlg Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -592,3 +592,21 @@ _rb_parent(const struct rb_type *t, void *node)
return (rbe == NULL ? NULL : rb_e2n(t, rbe));
}
+void
+_rb_poison(const struct rb_type *t, void *node, unsigned long poison)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+
+ RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
+ (struct rb_entry *)poison;
+}
+
+int
+_rb_check(const struct rb_type *t, void *node, unsigned long poison)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+
+ return ((unsigned long)RBE_PARENT(rbe) == poison &&
+ (unsigned long)RBE_LEFT(rbe) == poison &&
+ (unsigned long)RBE_RIGHT(rbe) == poison);
+}
diff --git a/sys/sys/tree.h b/sys/sys/tree.h
index 34d97739544..e8e729c8a0d 100644
--- a/sys/sys/tree.h
+++ b/sys/sys/tree.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tree.h,v 1.23 2016/09/15 05:21:09 dlg Exp $ */
+/* $OpenBSD: tree.h,v 1.24 2016/09/15 06:07:22 dlg Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
@@ -815,6 +815,8 @@ void *_rb_left(const struct rb_type *, void *);
void *_rb_right(const struct rb_type *, void *);
void *_rb_parent(const struct rb_type *, void *);
void *_rb_color(const struct rb_type *, void *);
+void _rb_poison(const struct rb_type *, void *, unsigned long);
+int _rb_check(const struct rb_type *, void *, unsigned long);
#define RBT_INITIALIZER(_head) { { NULL } }
@@ -903,6 +905,18 @@ static inline struct _type * \
_name##_RBT_PARENT(struct _type *elm) \
{ \
return _rb_parent(_name##_RBT_TYPE, elm); \
+} \
+ \
+static inline void \
+_name##_RBT_POISON(struct _type *elm, unsigned long poison) \
+{ \
+ return _rb_poison(_name##_RBT_TYPE, elm, poison); \
+} \
+ \
+static inline int \
+_name##_RBT_CHECK(struct _type *elm, unsigned long poison) \
+{ \
+ return _rb_check(_name##_RBT_TYPE, elm, poison); \
}
#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
@@ -945,6 +959,8 @@ RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)
#define RBT_LEFT(_name, _elm) _name##_RBT_LEFT(_elm)
#define RBT_RIGHT(_name, _elm) _name##_RBT_RIGHT(_elm)
#define RBT_PARENT(_name, _elm) _name##_RBT_PARENT(_elm)
+#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)
+#define RBT_CHECK(_name, _elm, _p) _name##_RBT_CHECK(_elm, _p)
#define RBT_FOREACH(_e, _name, _head) \
for ((_e) = RBT_MIN(_name, (_head)); \