]>
git.saurik.com Git - redis.git/blob - deps/jemalloc.orig/include/jemalloc/internal/rtree.h
2 * This radix tree implementation is tailored to the singular purpose of
3 * tracking which chunks are currently owned by jemalloc. This functionality
4 * is mandatory for OS X, where jemalloc must be able to respond to object
7 *******************************************************************************
9 #ifdef JEMALLOC_H_TYPES
11 typedef struct rtree_s rtree_t
;
14 * Size of each radix tree node (must be a power of 2). This impacts tree
17 #if (LG_SIZEOF_PTR == 2)
18 # define RTREE_NODESIZE (1U << 14)
20 # define RTREE_NODESIZE CACHELINE
23 #endif /* JEMALLOC_H_TYPES */
24 /******************************************************************************/
25 #ifdef JEMALLOC_H_STRUCTS
31 unsigned level2bits
[1]; /* Dynamically sized. */
34 #endif /* JEMALLOC_H_STRUCTS */
35 /******************************************************************************/
36 #ifdef JEMALLOC_H_EXTERNS
38 rtree_t
*rtree_new(unsigned bits
);
40 #endif /* JEMALLOC_H_EXTERNS */
41 /******************************************************************************/
42 #ifdef JEMALLOC_H_INLINES
44 #ifndef JEMALLOC_ENABLE_INLINE
45 #ifndef JEMALLOC_DEBUG
46 void *rtree_get_locked(rtree_t
*rtree
, uintptr_t key
);
48 void *rtree_get(rtree_t
*rtree
, uintptr_t key
);
49 bool rtree_set(rtree_t
*rtree
, uintptr_t key
, void *val
);
52 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_))
53 #define RTREE_GET_GENERATE(f) \
54 /* The least significant bits of the key are ignored. */ \
55 JEMALLOC_INLINE void * \
56 f(rtree_t *rtree, uintptr_t key) \
60 unsigned i, lshift, height, bits; \
61 void **node, **child; \
63 RTREE_LOCK(&rtree->mutex); \
64 for (i = lshift = 0, height = rtree->height, node = rtree->root;\
66 i++, lshift += bits, node = child) { \
67 bits = rtree->level2bits[i]; \
68 subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR + \
70 child = (void**)node[subkey]; \
71 if (child == NULL) { \
72 RTREE_UNLOCK(&rtree->mutex); \
78 * node is a leaf, so it contains values rather than node \
81 bits = rtree->level2bits[i]; \
82 subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR+3)) - \
85 RTREE_UNLOCK(&rtree->mutex); \
92 # define RTREE_LOCK(l) malloc_mutex_lock(l)
93 # define RTREE_UNLOCK(l) malloc_mutex_unlock(l)
94 # define RTREE_GET_VALIDATE
95 RTREE_GET_GENERATE(rtree_get_locked
)
98 # undef RTREE_GET_VALIDATE
101 #define RTREE_LOCK(l)
102 #define RTREE_UNLOCK(l)
103 #ifdef JEMALLOC_DEBUG
105 * Suppose that it were possible for a jemalloc-allocated chunk to be
106 * munmap()ped, followed by a different allocator in another thread re-using
107 * overlapping virtual memory, all without invalidating the cached rtree
108 * value. The result would be a false positive (the rtree would claim that
109 * jemalloc owns memory that it had actually discarded). This scenario
110 * seems impossible, but the following assertion is a prudent sanity check.
112 # define RTREE_GET_VALIDATE \
113 assert(rtree_get_locked(rtree, key) == ret);
115 # define RTREE_GET_VALIDATE
117 RTREE_GET_GENERATE(rtree_get
)
120 #undef RTREE_GET_VALIDATE
123 rtree_set(rtree_t
*rtree
, uintptr_t key
, void *val
)
126 unsigned i
, lshift
, height
, bits
;
127 void **node
, **child
;
129 malloc_mutex_lock(&rtree
->mutex
);
130 for (i
= lshift
= 0, height
= rtree
->height
, node
= rtree
->root
;
132 i
++, lshift
+= bits
, node
= child
) {
133 bits
= rtree
->level2bits
[i
];
134 subkey
= (key
<< lshift
) >> ((ZU(1) << (LG_SIZEOF_PTR
+3)) -
136 child
= (void**)node
[subkey
];
138 child
= (void**)base_alloc(sizeof(void *) <<
139 rtree
->level2bits
[i
+1]);
141 malloc_mutex_unlock(&rtree
->mutex
);
144 memset(child
, 0, sizeof(void *) <<
145 rtree
->level2bits
[i
+1]);
146 node
[subkey
] = child
;
150 /* node is a leaf, so it contains values rather than node pointers. */
151 bits
= rtree
->level2bits
[i
];
152 subkey
= (key
<< lshift
) >> ((ZU(1) << (LG_SIZEOF_PTR
+3)) - bits
);
154 malloc_mutex_unlock(&rtree
->mutex
);
160 #endif /* JEMALLOC_H_INLINES */
161 /******************************************************************************/