Home | History | Annotate | Download | only in internal
      1 /******************************************************************************/
      2 #ifdef JEMALLOC_H_TYPES
      3 
      4 /* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
      5 #define	LG_BITMAP_MAXBITS	LG_RUN_MAXREGS
      6 
      7 typedef struct bitmap_level_s bitmap_level_t;
      8 typedef struct bitmap_info_s bitmap_info_t;
      9 typedef unsigned long bitmap_t;
     10 #define	LG_SIZEOF_BITMAP	LG_SIZEOF_LONG
     11 
     12 /* Number of bits per group. */
     13 #define	LG_BITMAP_GROUP_NBITS		(LG_SIZEOF_BITMAP + 3)
     14 #define	BITMAP_GROUP_NBITS		(ZU(1) << LG_BITMAP_GROUP_NBITS)
     15 #define	BITMAP_GROUP_NBITS_MASK		(BITMAP_GROUP_NBITS-1)
     16 
     17 /* Maximum number of levels possible. */
     18 #define	BITMAP_MAX_LEVELS						\
     19     (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP)				\
     20     + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
     21 
     22 #endif /* JEMALLOC_H_TYPES */
     23 /******************************************************************************/
     24 #ifdef JEMALLOC_H_STRUCTS
     25 
     26 struct bitmap_level_s {
     27 	/* Offset of this level's groups within the array of groups. */
     28 	size_t group_offset;
     29 };
     30 
     31 struct bitmap_info_s {
     32 	/* Logical number of bits in bitmap (stored at bottom level). */
     33 	size_t nbits;
     34 
     35 	/* Number of levels necessary for nbits. */
     36 	unsigned nlevels;
     37 
     38 	/*
     39 	 * Only the first (nlevels+1) elements are used, and levels are ordered
     40 	 * bottom to top (e.g. the bottom level is stored in levels[0]).
     41 	 */
     42 	bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
     43 };
     44 
     45 #endif /* JEMALLOC_H_STRUCTS */
     46 /******************************************************************************/
     47 #ifdef JEMALLOC_H_EXTERNS
     48 
     49 void	bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
     50 size_t	bitmap_info_ngroups(const bitmap_info_t *binfo);
     51 size_t	bitmap_size(size_t nbits);
     52 void	bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo);
     53 
     54 #endif /* JEMALLOC_H_EXTERNS */
     55 /******************************************************************************/
     56 #ifdef JEMALLOC_H_INLINES
     57 
     58 #ifndef JEMALLOC_ENABLE_INLINE
     59 bool	bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo);
     60 bool	bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
     61 void	bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
     62 size_t	bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo);
     63 void	bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
     64 #endif
     65 
     66 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_))
     67 JEMALLOC_INLINE bool
     68 bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo)
     69 {
     70 	unsigned rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
     71 	bitmap_t rg = bitmap[rgoff];
     72 	/* The bitmap is full iff the root group is 0. */
     73 	return (rg == 0);
     74 }
     75 
     76 JEMALLOC_INLINE bool
     77 bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
     78 {
     79 	size_t goff;
     80 	bitmap_t g;
     81 
     82 	assert(bit < binfo->nbits);
     83 	goff = bit >> LG_BITMAP_GROUP_NBITS;
     84 	g = bitmap[goff];
     85 	return (!(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))));
     86 }
     87 
     88 JEMALLOC_INLINE void
     89 bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
     90 {
     91 	size_t goff;
     92 	bitmap_t *gp;
     93 	bitmap_t g;
     94 
     95 	assert(bit < binfo->nbits);
     96 	assert(bitmap_get(bitmap, binfo, bit) == false);
     97 	goff = bit >> LG_BITMAP_GROUP_NBITS;
     98 	gp = &bitmap[goff];
     99 	g = *gp;
    100 	assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
    101 	g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
    102 	*gp = g;
    103 	assert(bitmap_get(bitmap, binfo, bit));
    104 	/* Propagate group state transitions up the tree. */
    105 	if (g == 0) {
    106 		unsigned i;
    107 		for (i = 1; i < binfo->nlevels; i++) {
    108 			bit = goff;
    109 			goff = bit >> LG_BITMAP_GROUP_NBITS;
    110 			gp = &bitmap[binfo->levels[i].group_offset + goff];
    111 			g = *gp;
    112 			assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
    113 			g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
    114 			*gp = g;
    115 			if (g != 0)
    116 				break;
    117 		}
    118 	}
    119 }
    120 
    121 /* sfu: set first unset. */
    122 JEMALLOC_INLINE size_t
    123 bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo)
    124 {
    125 	size_t bit;
    126 	bitmap_t g;
    127 	unsigned i;
    128 
    129 	assert(bitmap_full(bitmap, binfo) == false);
    130 
    131 	i = binfo->nlevels - 1;
    132 	g = bitmap[binfo->levels[i].group_offset];
    133 	bit = jemalloc_ffsl(g) - 1;
    134 	while (i > 0) {
    135 		i--;
    136 		g = bitmap[binfo->levels[i].group_offset + bit];
    137 		bit = (bit << LG_BITMAP_GROUP_NBITS) + (jemalloc_ffsl(g) - 1);
    138 	}
    139 
    140 	bitmap_set(bitmap, binfo, bit);
    141 	return (bit);
    142 }
    143 
    144 JEMALLOC_INLINE void
    145 bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
    146 {
    147 	size_t goff;
    148 	bitmap_t *gp;
    149 	bitmap_t g;
    150 	bool propagate;
    151 
    152 	assert(bit < binfo->nbits);
    153 	assert(bitmap_get(bitmap, binfo, bit));
    154 	goff = bit >> LG_BITMAP_GROUP_NBITS;
    155 	gp = &bitmap[goff];
    156 	g = *gp;
    157 	propagate = (g == 0);
    158 	assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
    159 	g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
    160 	*gp = g;
    161 	assert(bitmap_get(bitmap, binfo, bit) == false);
    162 	/* Propagate group state transitions up the tree. */
    163 	if (propagate) {
    164 		unsigned i;
    165 		for (i = 1; i < binfo->nlevels; i++) {
    166 			bit = goff;
    167 			goff = bit >> LG_BITMAP_GROUP_NBITS;
    168 			gp = &bitmap[binfo->levels[i].group_offset + goff];
    169 			g = *gp;
    170 			propagate = (g == 0);
    171 			assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)))
    172 			    == 0);
    173 			g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
    174 			*gp = g;
    175 			if (propagate == false)
    176 				break;
    177 		}
    178 	}
    179 }
    180 
    181 #endif
    182 
    183 #endif /* JEMALLOC_H_INLINES */
    184 /******************************************************************************/
    185