Bit-un-rot the proplib portability layer.
This commit is contained in:
parent
3b3ffd7039
commit
c303bcbe4c
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile.inc,v 1.8 2008/06/30 20:14:09 matt Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.9 2012/07/27 09:10:59 pooka Exp $
|
||||
|
||||
.PATH: ${.PARSEDIR}
|
||||
|
||||
|
@ -6,4 +6,6 @@ SRCS+= prop_array.c prop_array_util.c prop_bool.c prop_data.c \
|
|||
prop_dictionary.c prop_dictionary_util.c prop_ingest.c \
|
||||
prop_kern.c prop_number.c prop_object.c prop_stack.c prop_string.c
|
||||
|
||||
#SRCS+= prop_rb.c
|
||||
.ifdef (PROPLIB_WANT_RB)
|
||||
SRCS+= prop_rb.c
|
||||
.endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_array.c,v 1.20 2008/08/11 05:54:21 christos Exp $ */
|
||||
/* $NetBSD: prop_array.c,v 1.21 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -29,8 +29,8 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <prop/prop_array.h>
|
||||
#include "prop_object_impl.h"
|
||||
#include <prop/prop_array.h>
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#include <errno.h>
|
||||
|
@ -340,7 +340,7 @@ static prop_object_t
|
|||
_prop_array_iterator_next_object(void *v)
|
||||
{
|
||||
struct _prop_array_iterator *pai = v;
|
||||
prop_array_t pa __unused = pai->pai_base.pi_obj;
|
||||
prop_array_t pa _PROP_ARG_UNUSED = pai->pai_base.pi_obj;
|
||||
prop_object_t po;
|
||||
|
||||
_PROP_ASSERT(prop_object_is_array(pa));
|
||||
|
@ -367,7 +367,7 @@ static void
|
|||
_prop_array_iterator_reset(void *v)
|
||||
{
|
||||
struct _prop_array_iterator *pai = v;
|
||||
prop_array_t pa __unused = pai->pai_base.pi_obj;
|
||||
prop_array_t pa _PROP_ARG_UNUSED = pai->pai_base.pi_obj;
|
||||
|
||||
_PROP_ASSERT(prop_object_is_array(pa));
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_array_util.c,v 1.3 2011/03/24 17:05:39 bouyer Exp $ */
|
||||
/* $NetBSD: prop_array_util.c,v 1.4 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -38,8 +38,8 @@
|
|||
* exactly what we're doing here.
|
||||
*/
|
||||
|
||||
#include <prop/proplib.h>
|
||||
#include "prop_object_impl.h" /* hide kernel vs. not-kernel vs. standalone */
|
||||
#include <prop/proplib.h>
|
||||
|
||||
bool
|
||||
prop_array_get_bool(prop_array_t array,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_dictionary.c,v 1.37 2011/04/20 19:40:00 martin Exp $ */
|
||||
/* $NetBSD: prop_dictionary.c,v 1.38 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -29,10 +29,10 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "prop_object_impl.h"
|
||||
#include <prop/prop_array.h>
|
||||
#include <prop/prop_dictionary.h>
|
||||
#include <prop/prop_string.h>
|
||||
#include "prop_object_impl.h"
|
||||
#include "prop_rb_impl.h"
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
|
@ -173,7 +173,7 @@ struct _prop_dictionary_iterator {
|
|||
|
||||
static int
|
||||
/*ARGSUSED*/
|
||||
_prop_dict_keysym_rb_compare_nodes(void *ctx __unused,
|
||||
_prop_dict_keysym_rb_compare_nodes(void *ctx _PROP_ARG_UNUSED,
|
||||
const void *n1, const void *n2)
|
||||
{
|
||||
const struct _prop_dictionary_keysym *pdk1 = n1;
|
||||
|
@ -184,7 +184,7 @@ _prop_dict_keysym_rb_compare_nodes(void *ctx __unused,
|
|||
|
||||
static int
|
||||
/*ARGSUSED*/
|
||||
_prop_dict_keysym_rb_compare_key(void *ctx __unused,
|
||||
_prop_dict_keysym_rb_compare_key(void *ctx _PROP_ARG_UNUSED,
|
||||
const void *n, const void *v)
|
||||
{
|
||||
const struct _prop_dictionary_keysym *pdk = n;
|
||||
|
@ -628,7 +628,7 @@ static prop_object_t
|
|||
_prop_dictionary_iterator_next_object(void *v)
|
||||
{
|
||||
struct _prop_dictionary_iterator *pdi = v;
|
||||
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
|
||||
prop_dictionary_t pd _PROP_ARG_UNUSED = pdi->pdi_base.pi_obj;
|
||||
prop_dictionary_keysym_t pdk;
|
||||
|
||||
_PROP_ASSERT(prop_object_is_dictionary(pd));
|
||||
|
@ -655,7 +655,7 @@ static void
|
|||
_prop_dictionary_iterator_reset(void *v)
|
||||
{
|
||||
struct _prop_dictionary_iterator *pdi = v;
|
||||
prop_dictionary_t pd __unused = pdi->pdi_base.pi_obj;
|
||||
prop_dictionary_t pd _PROP_ARG_UNUSED = pdi->pdi_base.pi_obj;
|
||||
|
||||
_PROP_RWLOCK_RDLOCK(pd->pd_rwlock);
|
||||
_prop_dictionary_iterator_reset_locked(pdi);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_dictionary_util.c,v 1.4 2011/03/24 17:05:39 bouyer Exp $ */
|
||||
/* $NetBSD: prop_dictionary_util.c,v 1.5 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -38,8 +38,8 @@
|
|||
* exactly what we're doing here.
|
||||
*/
|
||||
|
||||
#include <prop/proplib.h>
|
||||
#include "prop_object_impl.h" /* only to hide kernel vs. not-kernel */
|
||||
#include <prop/proplib.h>
|
||||
|
||||
bool
|
||||
prop_dictionary_get_dict(prop_dictionary_t dict, const char *key, prop_dictionary_t *dp)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_ingest.c,v 1.3 2008/04/28 20:22:53 martin Exp $ */
|
||||
/* $NetBSD: prop_ingest.c,v 1.4 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -29,8 +29,8 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <prop/proplib.h>
|
||||
#include "prop_object_impl.h"
|
||||
#include <prop/proplib.h>
|
||||
|
||||
struct _prop_ingest_context {
|
||||
prop_ingest_error_t pic_error;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_number.c,v 1.23 2010/09/24 22:51:52 rmind Exp $ */
|
||||
/* $NetBSD: prop_number.c,v 1.24 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -119,7 +119,7 @@ _prop_number_compare_values(const struct _prop_number_value *pnv1,
|
|||
|
||||
static int
|
||||
/*ARGSUSED*/
|
||||
_prop_number_rb_compare_nodes(void *ctx __unused,
|
||||
_prop_number_rb_compare_nodes(void *ctx _PROP_ARG_UNUSED,
|
||||
const void *n1, const void *n2)
|
||||
{
|
||||
const struct _prop_number *pn1 = n1;
|
||||
|
@ -130,7 +130,8 @@ _prop_number_rb_compare_nodes(void *ctx __unused,
|
|||
|
||||
static int
|
||||
/*ARGSUSED*/
|
||||
_prop_number_rb_compare_key(void *ctx __unused, const void *n, const void *v)
|
||||
_prop_number_rb_compare_key(void *ctx _PROP_ARG_UNUSED,
|
||||
const void *n, const void *v)
|
||||
{
|
||||
const struct _prop_number *pn = n;
|
||||
const struct _prop_number_value *pnv = v;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_object.c,v 1.27 2011/04/20 20:00:07 martin Exp $ */
|
||||
/* $NetBSD: prop_object.c,v 1.28 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006, 2007 The NetBSD Foundation, Inc.
|
||||
|
@ -29,8 +29,12 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <prop/prop_object.h>
|
||||
#include "prop_object_impl.h"
|
||||
#include <prop/prop_object.h>
|
||||
|
||||
#ifdef _PROP_NEED_REFCNT_MTX
|
||||
static pthread_mutex_t _prop_refcnt_mtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif /* _PROP_NEED_REFCNT_MTX */
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#include <sys/mman.h>
|
||||
|
@ -40,7 +44,6 @@
|
|||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/atomic.h>
|
||||
|
||||
#ifdef _STANDALONE
|
||||
void *
|
||||
|
@ -853,10 +856,14 @@ _prop_object_externalize_write_file(const char *fname, const char *xml,
|
|||
* and create the temporary file.
|
||||
*/
|
||||
_prop_object_externalize_file_dirname(fname, tname);
|
||||
if (strlcat(tname, "/.plistXXXXXX", sizeof(tname)) >= sizeof(tname)) {
|
||||
#define PLISTTMP "/.plistXXXXXX"
|
||||
if (strlen(tname) + strlen(PLISTTMP) >= sizeof(tname)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return (false);
|
||||
}
|
||||
strcat(tname, PLISTTMP);
|
||||
#undef PLISTTMP
|
||||
|
||||
if ((fd = mkstemp(tname)) == -1)
|
||||
return (false);
|
||||
|
||||
|
@ -982,7 +989,7 @@ prop_object_retain(prop_object_t obj)
|
|||
struct _prop_object *po = obj;
|
||||
uint32_t ncnt;
|
||||
|
||||
ncnt = atomic_inc_32_nv(&po->po_refcnt);
|
||||
_PROP_ATOMIC_INC32_NV(&po->po_refcnt, ncnt);
|
||||
_PROP_ASSERT(ncnt != 0);
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1021,7 @@ prop_object_release_emergency(prop_object_t obj)
|
|||
unlock = po->po_type->pot_unlock;
|
||||
|
||||
/* Dance a bit to make sure we always get the non-racy ocnt */
|
||||
ocnt = atomic_dec_32_nv(&po->po_refcnt);
|
||||
_PROP_ATOMIC_DEC32_NV(&po->po_refcnt, ocnt);
|
||||
ocnt++;
|
||||
_PROP_ASSERT(ocnt != 0);
|
||||
|
||||
|
@ -1036,7 +1043,7 @@ prop_object_release_emergency(prop_object_t obj)
|
|||
unlock();
|
||||
|
||||
parent = po;
|
||||
atomic_inc_32(&po->po_refcnt);
|
||||
_PROP_ATOMIC_INC32(&po->po_refcnt);
|
||||
}
|
||||
_PROP_ASSERT(parent);
|
||||
/* One object was just freed. */
|
||||
|
@ -1073,7 +1080,7 @@ prop_object_release(prop_object_t obj)
|
|||
/* Save pointer to object unlock function */
|
||||
unlock = po->po_type->pot_unlock;
|
||||
|
||||
ocnt = atomic_dec_32_nv(&po->po_refcnt);
|
||||
_PROP_ATOMIC_DEC32_NV(&po->po_refcnt, ocnt);
|
||||
ocnt++;
|
||||
_PROP_ASSERT(ocnt != 0);
|
||||
|
||||
|
@ -1092,7 +1099,7 @@ prop_object_release(prop_object_t obj)
|
|||
if (ret == _PROP_OBJECT_FREE_DONE)
|
||||
break;
|
||||
|
||||
atomic_inc_32(&po->po_refcnt);
|
||||
_PROP_ATOMIC_INC32(&po->po_refcnt);
|
||||
} while (ret == _PROP_OBJECT_FREE_RECURSE);
|
||||
if (ret == _PROP_OBJECT_FREE_FAILED)
|
||||
prop_object_release_emergency(obj);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_object_impl.h,v 1.30 2009/09/13 18:45:10 pooka Exp $ */
|
||||
/* $NetBSD: prop_object_impl.h,v 1.31 2012/07/27 09:10:59 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 The NetBSD Foundation, Inc.
|
||||
|
@ -293,6 +293,13 @@ __link_set_add_rodata(prop_linkpools, _link_ ## pp);
|
|||
#define _PROP_ONCE_DECL(x) static ONCE_DECL(x);
|
||||
#define _PROP_ONCE_RUN(x,f) RUN_ONCE(&(x), f)
|
||||
|
||||
#include <sys/atomic.h>
|
||||
|
||||
#define _PROP_ATOMIC_INC32(x) atomic_inc_32(x)
|
||||
#define _PROP_ATOMIC_DEC32(x) atomic_dec_32(x)
|
||||
#define _PROP_ATOMIC_INC32_NV(x, v) v = atomic_inc_32_nv(x)
|
||||
#define _PROP_ATOMIC_DEC32_NV(x, v) v = atomic_dec_32_nv(x)
|
||||
|
||||
#elif defined(_STANDALONE)
|
||||
|
||||
/*
|
||||
|
@ -333,6 +340,11 @@ void * _prop_standalone_realloc(void *, size_t);
|
|||
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
|
||||
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
|
||||
|
||||
#define _PROP_ATOMIC_INC32(x) ++*(x)
|
||||
#define _PROP_ATOMIC_DEC32(x) --*(x)
|
||||
#define _PROP_ATOMIC_INC32_NV(x, v) v = ++*(x)
|
||||
#define _PROP_ATOMIC_DEC32_NV(x, v) v = --*(x)
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
|
@ -364,6 +376,7 @@ void * _prop_standalone_realloc(void *, size_t);
|
|||
* Use the same mechanism as libc; we get pthread mutexes for threaded
|
||||
* programs and do-nothing stubs for non-threaded programs.
|
||||
*/
|
||||
#include <sys/atomic.h>
|
||||
#include "reentrant.h"
|
||||
#define _PROP_MUTEX_DECL_STATIC(x) static mutex_t x;
|
||||
#define _PROP_MUTEX_INIT(x) mutex_init(&(x), NULL)
|
||||
|
@ -381,6 +394,11 @@ void * _prop_standalone_realloc(void *, size_t);
|
|||
static pthread_once_t x = PTHREAD_ONCE_INIT;
|
||||
#define _PROP_ONCE_RUN(x,f) thr_once(&(x), (void(*)(void))f);
|
||||
|
||||
#define _PROP_ATOMIC_INC32(x) atomic_inc_32(x)
|
||||
#define _PROP_ATOMIC_DEC32(x) atomic_dec_32(x)
|
||||
#define _PROP_ATOMIC_INC32_NV(x, v) v = atomic_inc_32_nv(x)
|
||||
#define _PROP_ATOMIC_DEC32_NV(x, v) v = atomic_dec_32_nv(x)
|
||||
|
||||
#elif defined(HAVE_NBTOOL_CONFIG_H)
|
||||
/*
|
||||
* None of NetBSD's build tools are multi-threaded.
|
||||
|
@ -399,6 +417,12 @@ void * _prop_standalone_realloc(void *, size_t);
|
|||
|
||||
#define _PROP_ONCE_DECL(x) _PROP_NOTHREAD_ONCE_DECL(x)
|
||||
#define _PROP_ONCE_RUN(x,f) _PROP_NOTHREAD_ONCE_RUN(x,f)
|
||||
|
||||
#define _PROP_ATOMIC_INC32(x) ++*(x)
|
||||
#define _PROP_ATOMIC_DEC32(x) --*(x)
|
||||
#define _PROP_ATOMIC_INC32_NV(x, v) v = ++*(x)
|
||||
#define _PROP_ATOMIC_DEC32_NV(x, v) v = --*(x)
|
||||
|
||||
#else
|
||||
/*
|
||||
* Use pthread mutexes everywhere else.
|
||||
|
@ -419,8 +443,38 @@ void * _prop_standalone_realloc(void *, size_t);
|
|||
#define _PROP_ONCE_DECL(x) \
|
||||
static pthread_once_t x = PTHREAD_ONCE_INIT;
|
||||
#define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f)
|
||||
#endif
|
||||
|
||||
#define _PROP_NEED_REFCNT_MTX
|
||||
|
||||
#define _PROP_ATOMIC_INC32(x) \
|
||||
do { \
|
||||
pthread_mutex_lock(&_prop_refcnt_mtx); \
|
||||
(*(x))++; \
|
||||
pthread_mutex_unlock(&_prop_refcnt_mtx); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define _PROP_ATOMIC_DEC32(x) \
|
||||
do { \
|
||||
pthread_mutex_lock(&_prop_refcnt_mtx); \
|
||||
(*(x))--; \
|
||||
pthread_mutex_unlock(&_prop_refcnt_mtx); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define _PROP_ATOMIC_INC32_NV(x, v) \
|
||||
do { \
|
||||
pthread_mutex_lock(&_prop_refcnt_mtx); \
|
||||
v = ++(*(x)); \
|
||||
pthread_mutex_unlock(&_prop_refcnt_mtx); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define _PROP_ATOMIC_DEC32_NV(x, v) \
|
||||
do { \
|
||||
pthread_mutex_lock(&_prop_refcnt_mtx); \
|
||||
v = --(*(x)); \
|
||||
pthread_mutex_unlock(&_prop_refcnt_mtx); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: prop_rb_impl.h,v 1.8 2010/09/25 01:42:38 matt Exp $ */
|
||||
/* $NetBSD: prop_rb_impl.h,v 1.9 2012/07/27 09:11:00 pooka Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -47,107 +47,149 @@
|
|||
#else /* __NetBSD__ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef RBDEBUG
|
||||
#include <sys/queue.h>
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
struct rb_node {
|
||||
struct rb_node *rb_nodes[3];
|
||||
#define RB_NODE_LEFT 0
|
||||
#define RB_NODE_RIGHT 1
|
||||
#define RB_NODE_OTHER 1
|
||||
#define RB_NODE_PARENT 2
|
||||
#define rb_left rb_nodes[RB_NODE_LEFT]
|
||||
#define rb_right rb_nodes[RB_NODE_RIGHT]
|
||||
#define rb_parent rb_nodes[RB_NODE_PARENT]
|
||||
union {
|
||||
struct {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
unsigned int : 28;
|
||||
unsigned int s_root : 1;
|
||||
unsigned int s_position : 1;
|
||||
unsigned int s_color : 1;
|
||||
unsigned int s_sentinel : 1;
|
||||
#endif
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
unsigned int s_sentinel : 1;
|
||||
unsigned int s_color : 1;
|
||||
unsigned int s_position : 1;
|
||||
unsigned int s_root : 1;
|
||||
unsigned int : 28;
|
||||
#endif
|
||||
} u_s;
|
||||
unsigned int u_i;
|
||||
} rb_u;
|
||||
#define rb_root rb_u.u_s.s_root
|
||||
#define rb_position rb_u.u_s.s_position
|
||||
#define rb_color rb_u.u_s.s_color
|
||||
#define rb_sentinel rb_u.u_s.s_sentinel
|
||||
#define rb_properties rb_u.u_i
|
||||
#define RB_SENTINEL_P(rb) ((rb)->rb_sentinel + 0)
|
||||
#define RB_LEFT_SENTINEL_P(rb) ((rb)->rb_left->rb_sentinel + 0)
|
||||
#define RB_RIGHT_SENTINEL_P(rb) ((rb)->rb_right->rb_sentinel + 0)
|
||||
#define RB_PARENT_SENTINEL_P(rb) ((rb)->rb_parent->rb_sentinel + 0)
|
||||
#define RB_CHILDLESS_P(rb) (RB_LEFT_SENTINEL_P(rb) \
|
||||
&& RB_RIGHT_SENTINEL_P(rb))
|
||||
#define RB_TWOCHILDREN_P(rb) (!RB_LEFT_SENTINEL_P(rb) \
|
||||
&& !RB_RIGHT_SENTINEL_P(rb))
|
||||
#define RB_ROOT_P(rb) ((rb)->rb_root != false)
|
||||
#define RB_RED_P(rb) ((rb)->rb_color + 0)
|
||||
#define RB_BLACK_P(rb) (!(rb)->rb_color)
|
||||
#define RB_MARK_RED(rb) ((void)((rb)->rb_color = 1))
|
||||
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_color = 0))
|
||||
#define RB_MARK_ROOT(rb) ((void)((rb)->rb_root = 1))
|
||||
typedef struct rb_node {
|
||||
struct rb_node *rb_nodes[2];
|
||||
#define RB_DIR_LEFT 0
|
||||
#define RB_DIR_RIGHT 1
|
||||
#define RB_DIR_OTHER 1
|
||||
#define rb_left rb_nodes[RB_DIR_LEFT]
|
||||
#define rb_right rb_nodes[RB_DIR_RIGHT]
|
||||
|
||||
/*
|
||||
* rb_info contains the two flags and the parent back pointer.
|
||||
* We put the two flags in the low two bits since we know that
|
||||
* rb_node will have an alignment of 4 or 8 bytes.
|
||||
*/
|
||||
uintptr_t rb_info;
|
||||
#define RB_FLAG_POSITION 0x2
|
||||
#define RB_FLAG_RED 0x1
|
||||
#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
|
||||
#define RB_FATHER(rb) \
|
||||
((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
|
||||
#define RB_SET_FATHER(rb, father) \
|
||||
((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
|
||||
|
||||
#define RB_SENTINEL_P(rb) ((rb) == NULL)
|
||||
#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
|
||||
#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
|
||||
#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
|
||||
#define RB_CHILDLESS_P(rb) \
|
||||
(RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
|
||||
#define RB_TWOCHILDREN_P(rb) \
|
||||
(!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
|
||||
|
||||
#define RB_POSITION(rb) \
|
||||
(((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
|
||||
#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
|
||||
#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
|
||||
#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
|
||||
#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
|
||||
#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
|
||||
#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
|
||||
#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
|
||||
#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
|
||||
#define RB_SET_POSITION(rb, position) \
|
||||
((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
|
||||
((rb)->rb_info &= ~RB_FLAG_POSITION)))
|
||||
#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
|
||||
#define RB_COPY_PROPERTIES(dst, src) \
|
||||
((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
|
||||
#define RB_SWAP_PROPERTIES(a, b) do { \
|
||||
uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
|
||||
(a)->rb_info ^= xorinfo; \
|
||||
(b)->rb_info ^= xorinfo; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
#ifdef RBDEBUG
|
||||
TAILQ_ENTRY(rb_node) rb_link;
|
||||
#endif
|
||||
};
|
||||
} rb_node_t;
|
||||
|
||||
#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT)
|
||||
#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT)
|
||||
#define RB_TREE_FOREACH(N, T) \
|
||||
for ((N) = RB_TREE_MIN(T); (N); \
|
||||
(N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT))
|
||||
#define RB_TREE_FOREACH_REVERSE(N, T) \
|
||||
for ((N) = RB_TREE_MAX(T); (N); \
|
||||
(N) = rb_tree_iterate((T), (N), RB_DIR_LEFT))
|
||||
|
||||
#ifdef RBDEBUG
|
||||
TAILQ_HEAD(rb_node_qh, rb_node);
|
||||
|
||||
#define RB_TAILQ_REMOVE TAILQ_REMOVE
|
||||
#define RB_TAILQ_INIT TAILQ_INIT
|
||||
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD
|
||||
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE
|
||||
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER
|
||||
#define RB_TAILQ_REMOVE(a, b, c) TAILQ_REMOVE(a, b, c)
|
||||
#define RB_TAILQ_INIT(a) TAILQ_INIT(a)
|
||||
#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD(a, b, c)
|
||||
#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE(a, b, c)
|
||||
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER(a, b, c, d)
|
||||
#else
|
||||
#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||
#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0)
|
||||
#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||
#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0)
|
||||
#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0)
|
||||
#endif
|
||||
#endif /* RBDEBUG */
|
||||
|
||||
typedef int (*rb_compare_nodes_fn)(const struct rb_node *,
|
||||
const struct rb_node *);
|
||||
typedef int (*rb_compare_key_fn)(const struct rb_node *, const void *);
|
||||
/*
|
||||
* rbto_compare_nodes_fn:
|
||||
* return a positive value if the first node > the second node.
|
||||
* return a negative value if the first node < the second node.
|
||||
* return 0 if they are considered same.
|
||||
*
|
||||
* rbto_compare_key_fn:
|
||||
* return a positive value if the node > the key.
|
||||
* return a negative value if the node < the key.
|
||||
* return 0 if they are considered same.
|
||||
*/
|
||||
|
||||
struct rb_tree_ops {
|
||||
rb_compare_nodes_fn rbto_compare_nodes;
|
||||
rb_compare_key_fn rbto_compare_key;
|
||||
};
|
||||
typedef signed int (*rbto_compare_nodes_fn)(void *, const void *, const void *);
|
||||
typedef signed int (*rbto_compare_key_fn)(void *, const void *, const void *);
|
||||
|
||||
struct rb_tree {
|
||||
typedef struct {
|
||||
rbto_compare_nodes_fn rbto_compare_nodes;
|
||||
rbto_compare_key_fn rbto_compare_key;
|
||||
size_t rbto_node_offset;
|
||||
void *rbto_context;
|
||||
} rb_tree_ops_t;
|
||||
|
||||
typedef struct rb_tree {
|
||||
struct rb_node *rbt_root;
|
||||
const rb_tree_ops_t *rbt_ops;
|
||||
struct rb_node *rbt_minmax[2];
|
||||
#ifdef RBDEBUG
|
||||
struct rb_node_qh rbt_nodes;
|
||||
#endif
|
||||
const struct rb_tree_ops *rbt_ops;
|
||||
#ifdef RBDEBUG
|
||||
#ifdef RBSTATS
|
||||
unsigned int rbt_count;
|
||||
unsigned int rbt_insertions;
|
||||
unsigned int rbt_removals;
|
||||
unsigned int rbt_insertion_rebalance_calls;
|
||||
unsigned int rbt_insertion_rebalance_passes;
|
||||
unsigned int rbt_removal_rebalance_calls;
|
||||
unsigned int rbt_removal_rebalance_passes;
|
||||
#endif
|
||||
};
|
||||
} rb_tree_t;
|
||||
|
||||
void _prop_rb_tree_init(struct rb_tree *, const struct rb_tree_ops *);
|
||||
bool _prop_rb_tree_insert_node(struct rb_tree *, struct rb_node *);
|
||||
struct rb_node *
|
||||
_prop_rb_tree_find(struct rb_tree *, const void *);
|
||||
void _prop_rb_tree_remove_node(struct rb_tree *, struct rb_node *);
|
||||
#ifdef RBSTATS
|
||||
#define RBSTAT_INC(v) ((void)((v)++))
|
||||
#define RBSTAT_DEC(v) ((void)((v)--))
|
||||
#else
|
||||
#define RBSTAT_INC(v) do { } while (/*CONSTCOND*/0)
|
||||
#define RBSTAT_DEC(v) do { } while (/*CONSTCOND*/0)
|
||||
#endif
|
||||
|
||||
void _prop_rb_tree_init(rb_tree_t *, const rb_tree_ops_t *);
|
||||
void * _prop_rb_tree_insert_node(rb_tree_t *, void *);
|
||||
void * _prop_rb_tree_find(rb_tree_t *, const void *);
|
||||
void * _prop_rb_tree_find_node(rb_tree_t *, const void *);
|
||||
void _prop_rb_tree_remove_node(rb_tree_t *, void *);
|
||||
void * _prop_rb_tree_iterate(rb_tree_t *, void *, const unsigned int);
|
||||
#ifdef RBDEBUG
|
||||
void _prop_rb_tree_check(const struct rb_tree *, bool);
|
||||
#endif
|
||||
struct rb_node *
|
||||
_prop_rb_tree_iterate(struct rb_tree *, struct rb_node *, unsigned int);
|
||||
|
||||
#endif /* __NetBSD__ */
|
||||
|
||||
|
|
Loading…
Reference in New Issue