Commit 8f46188d authored by Philippe Gerum's avatar Philippe Gerum
Browse files

boilerplate/shavl: remove private memory references from shared data

The node search and comparison function addresses are process-local in
essence, do not share them.

Since some changes in this recent API were required, the few existing
users were converted to use the new API in the process.
parent 5c32d436
......@@ -72,10 +72,13 @@ __AVL_T(avl_search_t)(const struct __AVL_T(avl) *,
typedef int __AVL_T(avlh_prn_t)(char *, size_t,
const struct __AVL_T(avlh) *const);
struct __AVL_T(avl) {
struct __AVL_T(avlh) anchor;
struct __AVL_T(avl_searchops) {
__AVL_T(avl_search_t) *search;
__AVL_T(avlh_cmp_t) *cmp;
};
struct __AVL_T(avl) {
struct __AVL_T(avlh) anchor;
union {
ptrdiff_t offset;
struct __AVL_T(avlh) *ptr;
......@@ -123,8 +126,6 @@ shavl_set_end(struct shavl *const avl, int dir, struct shavlh *holder)
avl->end[avl_type2index(dir)].offset = (void *)holder - (void *)avl;
}
#define shavl_searchfn(avl) ((avl)->search)
#define shavl_cmp(avl) ((avl)->cmp)
#define shavl_count(avl) ((avl)->count)
#define shavl_height(avl) ((avl)->height)
#define shavl_anchor(avl) (&(avl)->anchor)
......@@ -202,8 +203,6 @@ avl_set_end(struct avl *const avl, int dir, struct avlh *holder)
avl_end(avl, dir) = holder;
}
#define avl_searchfn(avl) ((avl)->search)
#define avl_cmp(avl) ((avl)->cmp)
#define avl_count(avl) ((avl)->count)
#define avl_height(avl) ((avl)->height)
#define avl_anchor(avl) (&(avl)->anchor)
......@@ -280,9 +279,10 @@ avl_set_end(struct avl *const avl, int dir, struct avlh *holder)
static inline struct __AVL_T(avlh) *
__AVL(search_inner)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *n, int *delta)
const struct __AVL_T(avlh) *n, int *delta,
const struct __AVL_T(avl_searchops) *ops)
{
return __AVL(searchfn)(avl)(avl, n, delta, 0);
return ops->search(avl, n, delta, 0);
}
static inline
......@@ -371,12 +371,13 @@ static inline void __AVLH(init)(struct __AVL_T(avlh) *const holder)
static inline struct __AVL_T(avlh) *
__AVL(search)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node)
const struct __AVL_T(avlh) *node,
const struct __AVL_T(avl_searchops) *ops)
{
struct __AVL_T(avlh) *holder;
int delta;
holder = __AVL(search_inner)(avl, node, &delta);
holder = __AVL(search_inner)(avl, node, &delta, ops);
if (!delta)
return holder;
......@@ -385,12 +386,13 @@ __AVL(search)(const struct __AVL_T(avl) *const avl,
static inline struct __AVL_T(avlh) *
__AVL(search_nearest)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node, int dir)
const struct __AVL_T(avlh) *node, int dir,
const struct __AVL_T(avl_searchops) *ops)
{
struct __AVL_T(avlh) *holder;
int delta;
holder = __AVL(search_inner)(avl, node, &delta);
holder = __AVL(search_inner)(avl, node, &delta, ops);
if (!holder || delta != dir)
return holder;
......@@ -399,26 +401,29 @@ __AVL(search_nearest)(const struct __AVL_T(avl) *const avl,
static inline struct __AVL_T(avlh) *
__AVL(search_le)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node)
const struct __AVL_T(avlh) *node,
const struct __AVL_T(avl_searchops) *ops)
{
return __AVL(search_nearest)(avl, node, AVL_LEFT);
return __AVL(search_nearest)(avl, node, AVL_LEFT, ops);
}
static inline struct __AVL_T(avlh) *
__AVL(search_ge)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node)
const struct __AVL_T(avlh) *node,
const struct __AVL_T(avl_searchops) *ops)
{
return __AVL(search_nearest)(avl, node, AVL_RIGHT);
return __AVL(search_nearest)(avl, node, AVL_RIGHT, ops);
}
static inline struct __AVL_T(avlh) *
__AVL(search_multi)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node, int dir)
const struct __AVL_T(avlh) *node, int dir,
const struct __AVL_T(avl_searchops) *ops)
{
struct __AVL_T(avlh) *holder;
int delta;
holder = __AVL(searchfn)(avl)(avl, node, &delta, dir);
holder = ops->search(avl, node, &delta, dir);
if (!delta)
return holder;
......@@ -430,63 +435,73 @@ __AVL(search_multi)(const struct __AVL_T(avl) *const avl,
static inline struct __AVL_T(avlh) *
__AVL(search_first)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node)
const struct __AVL_T(avlh) *node,
const struct __AVL_T(avl_searchops) *ops)
{
return __AVL(search_multi)(avl, node, AVL_LEFT);
return __AVL(search_multi)(avl, node, AVL_LEFT, ops);
}
static inline struct __AVL_T(avlh) *
__AVL(search_last)(const struct __AVL_T(avl) *const avl,
const struct __AVL_T(avlh) *node)
const struct __AVL_T(avlh) *node,
const struct __AVL_T(avl_searchops) *ops)
{
return __AVL(search_multi)(avl, node, AVL_RIGHT);
return __AVL(search_multi)(avl, node, AVL_RIGHT, ops);
}
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void __AVL(init)(struct __AVL_T(avl) *const avl,
__AVL_T(avl_search_t) *searchfn, __AVL_T(avlh_cmp_t) *cmp);
void __AVL(init)(struct __AVL_T(avl) *const avl);
void __AVL(destroy)(struct __AVL_T(avl) *const avl);
int __AVL(insert)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *const holder);
struct __AVL_T(avlh) *const holder,
const struct __AVL_T(avl_searchops) *ops);
int __AVL(insert_front)(struct __AVL_T(avl) *avl,
struct __AVL_T(avlh) *holder);
struct __AVL_T(avlh) *holder,
const struct __AVL_T(avl_searchops) *ops);
int __AVL(insert_back)(struct __AVL_T(avl) *avl,
struct __AVL_T(avlh) *holder);
struct __AVL_T(avlh) *holder,
const struct __AVL_T(avl_searchops) *ops);
int __AVL(insert_at)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *parent, int dir,
struct __AVL_T(avlh) *parent, int dir,
struct __AVL_T(avlh) *child);
int __AVL(prepend)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *const holder);
struct __AVL_T(avlh) *const holder,
const struct __AVL_T(avl_searchops) *ops);
int __AVL(append)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *const holder);
struct __AVL_T(avlh) *const holder,
const struct __AVL_T(avl_searchops) *ops);
int __AVL(delete)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *node);
int __AVL(replace)(struct __AVL_T(avl) *avl,
struct __AVL_T(avlh) *oldh,
struct __AVL_T(avlh) *newh);
struct __AVL_T(avlh) *newh,
const struct __AVL_T(avl_searchops) *ops);
struct __AVL_T(avlh) *__AVL(update)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *const holder);
struct __AVL_T(avlh) *const holder,
const struct __AVL_T(avl_searchops) *ops);
struct __AVL_T(avlh) *__AVL(set)(struct __AVL_T(avl) *const avl,
struct __AVL_T(avlh) *const holder);
struct __AVL_T(avlh) *const holder,
const struct __AVL_T(avl_searchops) *ops);
void __AVL(clear)(struct __AVL_T(avl) *const avl,
void (*destruct)(struct __AVL_T(avlh) *));
int __AVL(check)(const struct __AVL_T(avl) *avl);
int __AVL(check)(const struct __AVL_T(avl) *avl,
const struct __AVL_T(avl_searchops) *ops);
void __AVL(dump)(FILE *file, const struct __AVL_T(avl) *const avl,
__AVL_T(avlh_prn_t) *prn, unsigned int indent,
......
......@@ -459,12 +459,13 @@ static int avl_delete_2children(struct __AVL_T (avl) * const avl,
}
int __AVL(prepend)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
struct __AVL_T (avlh) * const parent = __AVL(head)(avl);
int type = parent == NULL ? AVL_RIGHT : AVL_LEFT;
if (parent == NULL || __AVL(cmp)(avl)(holder, parent) < 0) {
if (parent == NULL || ops->cmp(holder, parent) < 0) {
avl_insert_inner(avl, parent, holder, type);
return 0;
}
......@@ -488,12 +489,13 @@ int __AVL(insert_at)(struct __AVL_T(avl) * const avl,
}
int __AVL(insert)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
int delta;
struct __AVL_T (avlh) * parent;
parent = __AVL(search_inner)(avl, holder, &delta);
parent = __AVL(search_inner)(avl, holder, &delta, ops);
if (delta == 0)
return -EBUSY;
......@@ -503,35 +505,38 @@ int __AVL(insert)(struct __AVL_T(avl) * const avl,
}
int __AVL(insert_front)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
int delta;
struct __AVL_T (avlh) * parent;
parent = __AVL(searchfn)(avl)(avl, holder, &delta, AVL_LEFT);
parent = ops->search(avl, holder, &delta, AVL_LEFT);
avl_insert_inner(avl, parent, holder, delta ? : AVL_LEFT);
return 0;
}
int __AVL(insert_back)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
int delta;
struct __AVL_T (avlh) * parent;
parent = __AVL(searchfn)(avl)(avl, holder, &delta, AVL_RIGHT);
parent = ops->search(avl, holder, &delta, AVL_RIGHT);
avl_insert_inner(avl, parent, holder, delta ? : AVL_RIGHT);
return 0;
}
int __AVL(append)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
struct __AVL_T (avlh) * const parent = __AVL(tail)(avl);
if (parent == NULL || __AVL(cmp)(avl)(holder, parent) > 0) {
if (parent == NULL || ops->cmp(holder, parent) > 0) {
avl_insert_inner(avl, parent, holder, AVL_RIGHT);
return 0;
}
......@@ -544,15 +549,16 @@ int __AVL(append)(struct __AVL_T(avl) * const avl,
* the avl, much faster than remove + add
*/
int __AVL(replace)(struct __AVL_T(avl) * avl, struct __AVL_T(avlh) * oldh,
struct __AVL_T(avlh) * newh)
struct __AVL_T(avlh) * newh,
const struct __AVL_T(avl_searchops) * ops)
{
struct __AVL_T (avlh) * prev, *next;
prev = __AVL(prev)(avl, oldh);
next = __AVL(next)(avl, oldh);
if ((prev && __AVL(cmp)(avl)(newh, prev) < 0)
|| (next && __AVL(cmp)(avl)(newh, next) > 0))
if ((prev && ops->cmp(newh, prev) < 0)
|| (next && ops->cmp(newh, next) > 0))
return -EINVAL;
avlh_replace(avl, oldh, newh);
......@@ -565,14 +571,15 @@ int __AVL(replace)(struct __AVL_T(avl) * avl, struct __AVL_T(avlh) * oldh,
}
struct __AVL_T (avlh) * __AVL(update)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
int delta;
struct __AVL_T (avlh) * const oldh =
__AVL(search_inner)(avl, holder, &delta);
__AVL(search_inner)(avl, holder, &delta, ops);
if (!delta) {
__AVL(replace)(avl, oldh, holder);
__AVL(replace)(avl, oldh, holder, ops);
return oldh;
}
......@@ -580,29 +587,27 @@ struct __AVL_T (avlh) * __AVL(update)(struct __AVL_T(avl) * const avl,
}
struct __AVL_T (avlh) * __AVL(set)(struct __AVL_T(avl) * const avl,
struct __AVL_T(avlh) * const holder)
struct __AVL_T(avlh) * const holder,
const struct __AVL_T(avl_searchops) * ops)
{
int delta;
struct __AVL_T (avlh) * const oldh =
__AVL(search_inner)(avl, holder, &delta);
__AVL(search_inner)(avl, holder, &delta, ops);
if (delta) {
avl_insert_inner(avl, oldh, holder, delta);
return NULL;
}
__AVL(replace)(avl, oldh, holder);
__AVL(replace)(avl, oldh, holder, ops);
return oldh;
}
void __AVL(init)(struct __AVL_T(avl) * const avl,
__AVL_T(avl_search_t) * searchfn, __AVL_T(avlh_cmp_t) * cmp)
void __AVL(init)(struct __AVL_T(avl) * const avl)
{
__AVLH(init)(__AVL(anchor)(avl)); /* this must be first. */
__AVL(cmp)(avl) = cmp;
__AVL(height)(avl) = 0;
__AVL(count)(avl) = 0;
__AVL(searchfn)(avl) = searchfn;
avl_set_top(avl, NULL);
avl_set_head(avl, NULL);
......@@ -611,7 +616,7 @@ void __AVL(init)(struct __AVL_T(avl) * const avl,
void __AVL(destroy)(struct __AVL_T(avl) * const avl)
{
__AVL(init)(avl, NULL, NULL);
__AVL(init)(avl);
}
void __AVL(clear)(struct __AVL_T(avl) * const avl,
......@@ -627,7 +632,7 @@ void __AVL(clear)(struct __AVL_T(avl) * const avl,
}
}
__AVL(init)(avl, NULL, NULL);
__AVL(init)(avl);
}
static inline
......@@ -745,7 +750,8 @@ check_balance:
return 0;
}
int __AVL(check)(const struct __AVL_T(avl) * avl)
int __AVL(check)(const struct __AVL_T(avl) * avl,
const struct __AVL_T(avl_searchops) * ops)
{
struct __AVL_T (avlh) * holder = __AVL(gettop)(avl), *last;
int err;
......@@ -761,7 +767,7 @@ int __AVL(check)(const struct __AVL_T(avl) * avl)
for (holder = __AVL(gethead)(avl); holder;
holder = __AVL(next)(avl, holder)) {
if (last != NULL)
if (__AVL(cmp)(avl)(holder, last) < 0) {
if (ops->cmp(holder, last) < 0) {
fprintf(stderr, "disordered nodes\n");
return -EINVAL;
}
......
......@@ -40,6 +40,9 @@ enum heapmem_pgtype {
page_list =2
};
static struct avl_searchops size_search_ops;
static struct avl_searchops addr_search_ops;
static inline uint32_t __attribute__ ((always_inline))
gen_block_mask(int log2size)
{
......@@ -148,7 +151,8 @@ find_suitable_range(struct heapmem_extent *ext, size_t size)
struct avlh *node;
lookup.size = size;
node = avl_search_ge(&ext->size_tree, &lookup.size_node);
node = avl_search_ge(&ext->size_tree, &lookup.size_node,
&size_search_ops);
if (node == NULL)
return NULL;
......@@ -179,7 +183,8 @@ static int reserve_page_range(struct heapmem_extent *ext, size_t size)
splitr->size -= size;
new = (struct heapmem_range *)((void *)new + splitr->size);
avlh_init(&splitr->size_node);
avl_insert_back(&ext->size_tree, &splitr->size_node);
avl_insert_back(&ext->size_tree, &splitr->size_node,
&size_search_ops);
return addr_to_pagenr(ext, new);
}
......@@ -189,7 +194,8 @@ find_left_neighbour(struct heapmem_extent *ext, struct heapmem_range *r)
{
struct avlh *node;
node = avl_search_le(&ext->addr_tree, &r->addr_node);
node = avl_search_le(&ext->addr_tree, &r->addr_node,
&addr_search_ops);
if (node == NULL)
return NULL;
......@@ -201,7 +207,8 @@ find_right_neighbour(struct heapmem_extent *ext, struct heapmem_range *r)
{
struct avlh *node;
node = avl_search_ge(&ext->addr_tree, &r->addr_node);
node = avl_search_ge(&ext->addr_tree, &r->addr_node,
&addr_search_ops);
if (node == NULL)
return NULL;
......@@ -251,17 +258,20 @@ static void release_page_range(struct heapmem_extent *ext,
avl_delete(&ext->addr_tree, &right->addr_node);
else
avl_replace(&ext->addr_tree, &right->addr_node,
&freed->addr_node);
&freed->addr_node, &addr_search_ops);
} else if (!addr_linked) {
avlh_init(&freed->addr_node);
if (left)
avl_insert(&ext->addr_tree, &freed->addr_node);
avl_insert(&ext->addr_tree, &freed->addr_node,
&addr_search_ops);
else
avl_prepend(&ext->addr_tree, &freed->addr_node);
avl_prepend(&ext->addr_tree, &freed->addr_node,
&addr_search_ops);
}
avlh_init(&freed->size_node);
avl_insert_back(&ext->size_tree, &freed->size_node);
avl_insert_back(&ext->size_tree, &freed->size_node,
&size_search_ops);
mark_pages(ext, addr_to_pagenr(ext, page),
size >> HEAPMEM_PAGE_SHIFT, page_free);
}
......@@ -575,6 +585,11 @@ static inline int compare_range_by_size(const struct avlh *l, const struct avlh
}
static DECLARE_AVL_SEARCH(search_range_by_size, compare_range_by_size);
static struct avl_searchops size_search_ops = {
.search = search_range_by_size,
.cmp = compare_range_by_size,
};
static inline int compare_range_by_addr(const struct avlh *l, const struct avlh *r)
{
uintptr_t al = (uintptr_t)l, ar = (uintptr_t)r;
......@@ -583,6 +598,11 @@ static inline int compare_range_by_addr(const struct avlh *l, const struct avlh
}
static DECLARE_AVL_SEARCH(search_range_by_addr, compare_range_by_addr);
static struct avl_searchops addr_search_ops = {
.search = search_range_by_addr,
.cmp = compare_range_by_addr,
};
static int add_extent(struct heap_memory *heap, void *mem, size_t size)
{
size_t user_size, overhead;
......@@ -651,8 +671,8 @@ static int add_extent(struct heap_memory *heap, void *mem, size_t size)
* extent. Over time, that range will be split then possibly
* re-merged back as allocations and deallocations take place.
*/
avl_init(&ext->size_tree, search_range_by_size, compare_range_by_size);
avl_init(&ext->addr_tree, search_range_by_addr, compare_range_by_addr);
avl_init(&ext->size_tree);
avl_init(&ext->addr_tree);
release_page_range(ext, ext->membase, user_size);
write_lock_safe(&heap->lock, state);
......
......@@ -52,6 +52,9 @@ enum sheapmem_pgtype {
page_list =2
};
static struct shavl_searchops size_search_ops;
static struct shavl_searchops addr_search_ops;
/*
* The main heap consists of a shared heap at its core, with
* additional session-wide information.
......@@ -201,7 +204,8 @@ find_suitable_range(struct sheapmem_extent *ext, size_t size)
struct shavlh *node;
lookup.size = size;
node = shavl_search_ge(&ext->size_tree, &lookup.size_node);
node = shavl_search_ge(&ext->size_tree, &lookup.size_node,
&size_search_ops);
if (node == NULL)
return NULL;
......@@ -232,7 +236,8 @@ static int reserve_page_range(struct sheapmem_extent *ext, size_t size)
splitr->size -= size;
new = (struct sheapmem_range *)((void *)new + splitr->size);
shavlh_init(&splitr->size_node);
shavl_insert_back(&ext->size_tree, &splitr->size_node);
shavl_insert_back(&ext->size_tree, &splitr->size_node,
&size_search_ops);
return addr_to_pagenr(ext, new);
}
......@@ -242,7 +247,8 @@ find_left_neighbour(struct sheapmem_extent *ext, struct sheapmem_range *r)
{
struct shavlh *node;
node = shavl_search_le(&ext->addr_tree, &r->addr_node);
node = shavl_search_le(&ext->addr_tree, &r->addr_node,
&addr_search_ops);
if (node == NULL)
return NULL;
......@@ -254,7 +260,8 @@ find_right_neighbour(struct sheapmem_extent *ext, struct sheapmem_range *r)
{
struct shavlh *node;
node = shavl_search_ge(&ext->addr_tree, &r->addr_node);
node = shavl_search_ge(&ext->addr_tree, &r->addr_node,
&addr_search_ops);
if (node == NULL)
return NULL;
......@@ -304,17 +311,20 @@ static void release_page_range(struct sheapmem_extent *ext,
shavl_delete(&ext->addr_tree, &right->addr_node);
else
shavl_replace(&ext->addr_tree, &right->addr_node,
&freed->addr_node);
&freed->addr_node, &addr_search_ops);
} else if (!addr_linked) {
shavlh_init(&freed->addr_node);
if (left)
shavl_insert(&ext->addr_tree, &freed->addr_node);
shavl_insert(&ext->addr_tree, &freed->addr_node,
&addr_search_ops);
else
shavl_prepend(&ext->addr_tree, &freed->addr_node);
shavl_prepend(&ext->addr_tree, &freed->addr_node,
&addr_search_ops);
}
shavlh_init(&freed->size_node);
shavl_insert_back(&ext->size_tree, &freed->size_node);
shavl_insert_back(&ext->size_tree, &freed->size_node,
&size_search_ops);
mark_pages(ext, addr_to_pagenr(ext, page),
size >> SHEAPMEM_PAGE_SHIFT, page_free);
}
......@@ -629,6 +639,11 @@ static inline int compare_range_by_size(const struct shavlh *l, const struct sha
}
static DECLARE_SHAVL_SEARCH(search_range_by_size, compare_range_by_size);
static struct shavl_searchops size_search_ops = {
.search = search_range_by_size,
.cmp = compare_range_by_size,
};
static inline int compare_range_by_addr(const struct shavlh *l, const struct shavlh *r)
{
uintptr_t al = (uintptr_t)l, ar = (uintptr_t)r;
......@@ -637,6 +652,11 @@ static inline int compare_range_by_addr(const struct shavlh *l, const struct sha
}
static DECLARE_SHAVL_SEARCH(search_range_by_addr, compare_range_by_addr);
static struct shavl_searchops addr_search_ops = {
.search = search_range_by_addr,
.cmp = compare_range_by_addr,
};
static int add_extent(struct shared_heap_memory *heap, void *base,
void *mem, size_t size)
{
......@@ -707,8 +727,8 @@ static int add_extent(struct shared_heap_memory *heap, void *base,
* extent. Over time, that range will be split then possibly
* re-merged back as allocations and deallocations take place.
*/
shavl_init(&ext->size_tree, search_range_by_size, compare_range_by_size);
shavl_init(&ext->addr_tree, search_range_by_addr, compare_range_by_addr);
shavl_init(&ext->size_tree);
shavl_init(&ext->addr_tree);
release_page_range(ext, __shref(base, ext->membase), user_size);
write_lock_safe(&heap->lock, state);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment