Home | History | Annotate | Download | only in src
      1 #define	JEMALLOC_RTREE_C_
      2 #include "jemalloc/internal/jemalloc_internal.h"
      3 
      4 rtree_t *
      5 rtree_new(unsigned bits, rtree_alloc_t *alloc, rtree_dalloc_t *dalloc)
      6 {
      7 	rtree_t *ret;
      8 	unsigned bits_per_level, bits_in_leaf, height, i;
      9 
     10 	assert(bits > 0 && bits <= (sizeof(uintptr_t) << 3));
     11 
     12 	bits_per_level = jemalloc_ffs(pow2_ceil((RTREE_NODESIZE / sizeof(void *)))) - 1;
     13 	bits_in_leaf = jemalloc_ffs(pow2_ceil((RTREE_NODESIZE / sizeof(uint8_t)))) - 1;
     14 	if (bits > bits_in_leaf) {
     15 		height = 1 + (bits - bits_in_leaf) / bits_per_level;
     16 		if ((height-1) * bits_per_level + bits_in_leaf != bits)
     17 			height++;
     18 	} else {
     19 		height = 1;
     20 	}
     21 	assert((height-1) * bits_per_level + bits_in_leaf >= bits);
     22 
     23 	ret = (rtree_t*)alloc(offsetof(rtree_t, level2bits) +
     24 	    (sizeof(unsigned) * height));
     25 	if (ret == NULL)
     26 		return (NULL);
     27 	memset(ret, 0, offsetof(rtree_t, level2bits) + (sizeof(unsigned) *
     28 	    height));
     29 
     30 	ret->alloc = alloc;
     31 	ret->dalloc = dalloc;
     32 	if (malloc_mutex_init(&ret->mutex)) {
     33 		if (dalloc != NULL)
     34 			dalloc(ret);
     35 		return (NULL);
     36 	}
     37 	ret->height = height;
     38 	if (height > 1) {
     39 		if ((height-1) * bits_per_level + bits_in_leaf > bits) {
     40 			ret->level2bits[0] = (bits - bits_in_leaf) %
     41 			    bits_per_level;
     42 		} else
     43 			ret->level2bits[0] = bits_per_level;
     44 		for (i = 1; i < height-1; i++)
     45 			ret->level2bits[i] = bits_per_level;
     46 		ret->level2bits[height-1] = bits_in_leaf;
     47 	} else
     48 		ret->level2bits[0] = bits;
     49 
     50 	ret->root = (void**)alloc(sizeof(void *) << ret->level2bits[0]);
     51 	if (ret->root == NULL) {
     52 		if (dalloc != NULL)
     53 			dalloc(ret);
     54 		return (NULL);
     55 	}
     56 	memset(ret->root, 0, sizeof(void *) << ret->level2bits[0]);
     57 
     58 	return (ret);
     59 }
     60 
     61 static void
     62 rtree_delete_subtree(rtree_t *rtree, void **node, unsigned level)
     63 {
     64 
     65 	if (level < rtree->height - 1) {
     66 		size_t nchildren, i;
     67 
     68 		nchildren = ZU(1) << rtree->level2bits[level];
     69 		for (i = 0; i < nchildren; i++) {
     70 			void **child = (void **)node[i];
     71 			if (child != NULL)
     72 				rtree_delete_subtree(rtree, child, level + 1);
     73 		}
     74 	}
     75 	rtree->dalloc(node);
     76 }
     77 
     78 void
     79 rtree_delete(rtree_t *rtree)
     80 {
     81 
     82 	rtree_delete_subtree(rtree, rtree->root, 0);
     83 	rtree->dalloc(rtree);
     84 }
     85 
     86 void
     87 rtree_prefork(rtree_t *rtree)
     88 {
     89 
     90 	malloc_mutex_prefork(&rtree->mutex);
     91 }
     92 
     93 void
     94 rtree_postfork_parent(rtree_t *rtree)
     95 {
     96 
     97 	malloc_mutex_postfork_parent(&rtree->mutex);
     98 }
     99 
    100 void
    101 rtree_postfork_child(rtree_t *rtree)
    102 {
    103 
    104 	malloc_mutex_postfork_child(&rtree->mutex);
    105 }
    106