xref: /netbsd-src/external/bsd/jemalloc.old/include/jemalloc/internal/bitmap.h (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_BITMAP_H
2*8e33eff8Schristos #define JEMALLOC_INTERNAL_BITMAP_H
3*8e33eff8Schristos 
4*8e33eff8Schristos #include "jemalloc/internal/arena_types.h"
5*8e33eff8Schristos #include "jemalloc/internal/bit_util.h"
6*8e33eff8Schristos #include "jemalloc/internal/size_classes.h"
7*8e33eff8Schristos 
8*8e33eff8Schristos typedef unsigned long bitmap_t;
9*8e33eff8Schristos #define LG_SIZEOF_BITMAP	LG_SIZEOF_LONG
10*8e33eff8Schristos 
11*8e33eff8Schristos /* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
12*8e33eff8Schristos #if LG_SLAB_MAXREGS > LG_CEIL_NSIZES
13*8e33eff8Schristos /* Maximum bitmap bit count is determined by maximum regions per slab. */
14*8e33eff8Schristos #  define LG_BITMAP_MAXBITS	LG_SLAB_MAXREGS
15*8e33eff8Schristos #else
16*8e33eff8Schristos /* Maximum bitmap bit count is determined by number of extent size classes. */
17*8e33eff8Schristos #  define LG_BITMAP_MAXBITS	LG_CEIL_NSIZES
18*8e33eff8Schristos #endif
19*8e33eff8Schristos #define BITMAP_MAXBITS		(ZU(1) << LG_BITMAP_MAXBITS)
20*8e33eff8Schristos 
21*8e33eff8Schristos /* Number of bits per group. */
22*8e33eff8Schristos #define LG_BITMAP_GROUP_NBITS		(LG_SIZEOF_BITMAP + 3)
23*8e33eff8Schristos #define BITMAP_GROUP_NBITS		(1U << LG_BITMAP_GROUP_NBITS)
24*8e33eff8Schristos #define BITMAP_GROUP_NBITS_MASK		(BITMAP_GROUP_NBITS-1)
25*8e33eff8Schristos 
26*8e33eff8Schristos /*
27*8e33eff8Schristos  * Do some analysis on how big the bitmap is before we use a tree.  For a brute
28*8e33eff8Schristos  * force linear search, if we would have to call ffs_lu() more than 2^3 times,
29*8e33eff8Schristos  * use a tree instead.
30*8e33eff8Schristos  */
31*8e33eff8Schristos #if LG_BITMAP_MAXBITS - LG_BITMAP_GROUP_NBITS > 3
32*8e33eff8Schristos #  define BITMAP_USE_TREE
33*8e33eff8Schristos #endif
34*8e33eff8Schristos 
35*8e33eff8Schristos /* Number of groups required to store a given number of bits. */
36*8e33eff8Schristos #define BITMAP_BITS2GROUPS(nbits)					\
37*8e33eff8Schristos     (((nbits) + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS)
38*8e33eff8Schristos 
39*8e33eff8Schristos /*
40*8e33eff8Schristos  * Number of groups required at a particular level for a given number of bits.
41*8e33eff8Schristos  */
42*8e33eff8Schristos #define BITMAP_GROUPS_L0(nbits)						\
43*8e33eff8Schristos     BITMAP_BITS2GROUPS(nbits)
44*8e33eff8Schristos #define BITMAP_GROUPS_L1(nbits)						\
45*8e33eff8Schristos     BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits))
46*8e33eff8Schristos #define BITMAP_GROUPS_L2(nbits)						\
47*8e33eff8Schristos     BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))
48*8e33eff8Schristos #define BITMAP_GROUPS_L3(nbits)						\
49*8e33eff8Schristos     BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(		\
50*8e33eff8Schristos 	BITMAP_BITS2GROUPS((nbits)))))
51*8e33eff8Schristos #define BITMAP_GROUPS_L4(nbits)						\
52*8e33eff8Schristos     BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(		\
53*8e33eff8Schristos 	BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))))
54*8e33eff8Schristos 
55*8e33eff8Schristos /*
56*8e33eff8Schristos  * Assuming the number of levels, number of groups required for a given number
57*8e33eff8Schristos  * of bits.
58*8e33eff8Schristos  */
59*8e33eff8Schristos #define BITMAP_GROUPS_1_LEVEL(nbits)					\
60*8e33eff8Schristos     BITMAP_GROUPS_L0(nbits)
61*8e33eff8Schristos #define BITMAP_GROUPS_2_LEVEL(nbits)					\
62*8e33eff8Schristos     (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits))
63*8e33eff8Schristos #define BITMAP_GROUPS_3_LEVEL(nbits)					\
64*8e33eff8Schristos     (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits))
65*8e33eff8Schristos #define BITMAP_GROUPS_4_LEVEL(nbits)					\
66*8e33eff8Schristos     (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits))
67*8e33eff8Schristos #define BITMAP_GROUPS_5_LEVEL(nbits)					\
68*8e33eff8Schristos     (BITMAP_GROUPS_4_LEVEL(nbits) + BITMAP_GROUPS_L4(nbits))
69*8e33eff8Schristos 
70*8e33eff8Schristos /*
71*8e33eff8Schristos  * Maximum number of groups required to support LG_BITMAP_MAXBITS.
72*8e33eff8Schristos  */
73*8e33eff8Schristos #ifdef BITMAP_USE_TREE
74*8e33eff8Schristos 
75*8e33eff8Schristos #if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS
76*8e33eff8Schristos #  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_1_LEVEL(nbits)
77*8e33eff8Schristos #  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS)
78*8e33eff8Schristos #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2
79*8e33eff8Schristos #  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_2_LEVEL(nbits)
80*8e33eff8Schristos #  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS)
81*8e33eff8Schristos #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3
82*8e33eff8Schristos #  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_3_LEVEL(nbits)
83*8e33eff8Schristos #  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS)
84*8e33eff8Schristos #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4
85*8e33eff8Schristos #  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_4_LEVEL(nbits)
86*8e33eff8Schristos #  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS)
87*8e33eff8Schristos #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 5
88*8e33eff8Schristos #  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_5_LEVEL(nbits)
89*8e33eff8Schristos #  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_5_LEVEL(BITMAP_MAXBITS)
90*8e33eff8Schristos #else
91*8e33eff8Schristos #  error "Unsupported bitmap size"
92*8e33eff8Schristos #endif
93*8e33eff8Schristos 
94*8e33eff8Schristos /*
95*8e33eff8Schristos  * Maximum number of levels possible.  This could be statically computed based
96*8e33eff8Schristos  * on LG_BITMAP_MAXBITS:
97*8e33eff8Schristos  *
98*8e33eff8Schristos  * #define BITMAP_MAX_LEVELS \
99*8e33eff8Schristos  *     (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \
100*8e33eff8Schristos  *     + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
101*8e33eff8Schristos  *
102*8e33eff8Schristos  * However, that would not allow the generic BITMAP_INFO_INITIALIZER() macro, so
103*8e33eff8Schristos  * instead hardcode BITMAP_MAX_LEVELS to the largest number supported by the
104*8e33eff8Schristos  * various cascading macros.  The only additional cost this incurs is some
105*8e33eff8Schristos  * unused trailing entries in bitmap_info_t structures; the bitmaps themselves
106*8e33eff8Schristos  * are not impacted.
107*8e33eff8Schristos  */
108*8e33eff8Schristos #define BITMAP_MAX_LEVELS	5
109*8e33eff8Schristos 
110*8e33eff8Schristos #define BITMAP_INFO_INITIALIZER(nbits) {				\
111*8e33eff8Schristos 	/* nbits. */							\
112*8e33eff8Schristos 	nbits,								\
113*8e33eff8Schristos 	/* nlevels. */							\
114*8e33eff8Schristos 	(BITMAP_GROUPS_L0(nbits) > BITMAP_GROUPS_L1(nbits)) +		\
115*8e33eff8Schristos 	    (BITMAP_GROUPS_L1(nbits) > BITMAP_GROUPS_L2(nbits)) +	\
116*8e33eff8Schristos 	    (BITMAP_GROUPS_L2(nbits) > BITMAP_GROUPS_L3(nbits)) +	\
117*8e33eff8Schristos 	    (BITMAP_GROUPS_L3(nbits) > BITMAP_GROUPS_L4(nbits)) + 1,	\
118*8e33eff8Schristos 	/* levels. */							\
119*8e33eff8Schristos 	{								\
120*8e33eff8Schristos 		{0},							\
121*8e33eff8Schristos 		{BITMAP_GROUPS_L0(nbits)},				\
122*8e33eff8Schristos 		{BITMAP_GROUPS_L1(nbits) + BITMAP_GROUPS_L0(nbits)},	\
123*8e33eff8Schristos 		{BITMAP_GROUPS_L2(nbits) + BITMAP_GROUPS_L1(nbits) +	\
124*8e33eff8Schristos 		    BITMAP_GROUPS_L0(nbits)},				\
125*8e33eff8Schristos 		{BITMAP_GROUPS_L3(nbits) + BITMAP_GROUPS_L2(nbits) +	\
126*8e33eff8Schristos 		    BITMAP_GROUPS_L1(nbits) + BITMAP_GROUPS_L0(nbits)},	\
127*8e33eff8Schristos 		{BITMAP_GROUPS_L4(nbits) + BITMAP_GROUPS_L3(nbits) +	\
128*8e33eff8Schristos 		     BITMAP_GROUPS_L2(nbits) + BITMAP_GROUPS_L1(nbits)	\
129*8e33eff8Schristos 		     + BITMAP_GROUPS_L0(nbits)}				\
130*8e33eff8Schristos 	}								\
131*8e33eff8Schristos }
132*8e33eff8Schristos 
133*8e33eff8Schristos #else /* BITMAP_USE_TREE */
134*8e33eff8Schristos 
135*8e33eff8Schristos #define BITMAP_GROUPS(nbits)	BITMAP_BITS2GROUPS(nbits)
136*8e33eff8Schristos #define BITMAP_GROUPS_MAX	BITMAP_BITS2GROUPS(BITMAP_MAXBITS)
137*8e33eff8Schristos 
138*8e33eff8Schristos #define BITMAP_INFO_INITIALIZER(nbits) {				\
139*8e33eff8Schristos 	/* nbits. */							\
140*8e33eff8Schristos 	nbits,								\
141*8e33eff8Schristos 	/* ngroups. */							\
142*8e33eff8Schristos 	BITMAP_BITS2GROUPS(nbits)					\
143*8e33eff8Schristos }
144*8e33eff8Schristos 
145*8e33eff8Schristos #endif /* BITMAP_USE_TREE */
146*8e33eff8Schristos 
147*8e33eff8Schristos typedef struct bitmap_level_s {
148*8e33eff8Schristos 	/* Offset of this level's groups within the array of groups. */
149*8e33eff8Schristos 	size_t group_offset;
150*8e33eff8Schristos } bitmap_level_t;
151*8e33eff8Schristos 
152*8e33eff8Schristos typedef struct bitmap_info_s {
153*8e33eff8Schristos 	/* Logical number of bits in bitmap (stored at bottom level). */
154*8e33eff8Schristos 	size_t nbits;
155*8e33eff8Schristos 
156*8e33eff8Schristos #ifdef BITMAP_USE_TREE
157*8e33eff8Schristos 	/* Number of levels necessary for nbits. */
158*8e33eff8Schristos 	unsigned nlevels;
159*8e33eff8Schristos 
160*8e33eff8Schristos 	/*
161*8e33eff8Schristos 	 * Only the first (nlevels+1) elements are used, and levels are ordered
162*8e33eff8Schristos 	 * bottom to top (e.g. the bottom level is stored in levels[0]).
163*8e33eff8Schristos 	 */
164*8e33eff8Schristos 	bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
165*8e33eff8Schristos #else /* BITMAP_USE_TREE */
166*8e33eff8Schristos 	/* Number of groups necessary for nbits. */
167*8e33eff8Schristos 	size_t ngroups;
168*8e33eff8Schristos #endif /* BITMAP_USE_TREE */
169*8e33eff8Schristos } bitmap_info_t;
170*8e33eff8Schristos 
171*8e33eff8Schristos void bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
172*8e33eff8Schristos void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo, bool fill);
173*8e33eff8Schristos size_t bitmap_size(const bitmap_info_t *binfo);
174*8e33eff8Schristos 
175*8e33eff8Schristos static inline bool
176*8e33eff8Schristos bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo) {
177*8e33eff8Schristos #ifdef BITMAP_USE_TREE
178*8e33eff8Schristos 	size_t rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
179*8e33eff8Schristos 	bitmap_t rg = bitmap[rgoff];
180*8e33eff8Schristos 	/* The bitmap is full iff the root group is 0. */
181*8e33eff8Schristos 	return (rg == 0);
182*8e33eff8Schristos #else
183*8e33eff8Schristos 	size_t i;
184*8e33eff8Schristos 
185*8e33eff8Schristos 	for (i = 0; i < binfo->ngroups; i++) {
186*8e33eff8Schristos 		if (bitmap[i] != 0) {
187*8e33eff8Schristos 			return false;
188*8e33eff8Schristos 		}
189*8e33eff8Schristos 	}
190*8e33eff8Schristos 	return true;
191*8e33eff8Schristos #endif
192*8e33eff8Schristos }
193*8e33eff8Schristos 
194*8e33eff8Schristos static inline bool
195*8e33eff8Schristos bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
196*8e33eff8Schristos 	size_t goff;
197*8e33eff8Schristos 	bitmap_t g;
198*8e33eff8Schristos 
199*8e33eff8Schristos 	assert(bit < binfo->nbits);
200*8e33eff8Schristos 	goff = bit >> LG_BITMAP_GROUP_NBITS;
201*8e33eff8Schristos 	g = bitmap[goff];
202*8e33eff8Schristos 	return !(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
203*8e33eff8Schristos }
204*8e33eff8Schristos 
205*8e33eff8Schristos static inline void
206*8e33eff8Schristos bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
207*8e33eff8Schristos 	size_t goff;
208*8e33eff8Schristos 	bitmap_t *gp;
209*8e33eff8Schristos 	bitmap_t g;
210*8e33eff8Schristos 
211*8e33eff8Schristos 	assert(bit < binfo->nbits);
212*8e33eff8Schristos 	assert(!bitmap_get(bitmap, binfo, bit));
213*8e33eff8Schristos 	goff = bit >> LG_BITMAP_GROUP_NBITS;
214*8e33eff8Schristos 	gp = &bitmap[goff];
215*8e33eff8Schristos 	g = *gp;
216*8e33eff8Schristos 	assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
217*8e33eff8Schristos 	g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
218*8e33eff8Schristos 	*gp = g;
219*8e33eff8Schristos 	assert(bitmap_get(bitmap, binfo, bit));
220*8e33eff8Schristos #ifdef BITMAP_USE_TREE
221*8e33eff8Schristos 	/* Propagate group state transitions up the tree. */
222*8e33eff8Schristos 	if (g == 0) {
223*8e33eff8Schristos 		unsigned i;
224*8e33eff8Schristos 		for (i = 1; i < binfo->nlevels; i++) {
225*8e33eff8Schristos 			bit = goff;
226*8e33eff8Schristos 			goff = bit >> LG_BITMAP_GROUP_NBITS;
227*8e33eff8Schristos 			gp = &bitmap[binfo->levels[i].group_offset + goff];
228*8e33eff8Schristos 			g = *gp;
229*8e33eff8Schristos 			assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
230*8e33eff8Schristos 			g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
231*8e33eff8Schristos 			*gp = g;
232*8e33eff8Schristos 			if (g != 0) {
233*8e33eff8Schristos 				break;
234*8e33eff8Schristos 			}
235*8e33eff8Schristos 		}
236*8e33eff8Schristos 	}
237*8e33eff8Schristos #endif
238*8e33eff8Schristos }
239*8e33eff8Schristos 
240*8e33eff8Schristos /* ffu: find first unset >= bit. */
241*8e33eff8Schristos static inline size_t
242*8e33eff8Schristos bitmap_ffu(const bitmap_t *bitmap, const bitmap_info_t *binfo, size_t min_bit) {
243*8e33eff8Schristos 	assert(min_bit < binfo->nbits);
244*8e33eff8Schristos 
245*8e33eff8Schristos #ifdef BITMAP_USE_TREE
246*8e33eff8Schristos 	size_t bit = 0;
247*8e33eff8Schristos 	for (unsigned level = binfo->nlevels; level--;) {
248*8e33eff8Schristos 		size_t lg_bits_per_group = (LG_BITMAP_GROUP_NBITS * (level +
249*8e33eff8Schristos 		    1));
250*8e33eff8Schristos 		bitmap_t group = bitmap[binfo->levels[level].group_offset + (bit
251*8e33eff8Schristos 		    >> lg_bits_per_group)];
252*8e33eff8Schristos 		unsigned group_nmask = (unsigned)(((min_bit > bit) ? (min_bit -
253*8e33eff8Schristos 		    bit) : 0) >> (lg_bits_per_group - LG_BITMAP_GROUP_NBITS));
254*8e33eff8Schristos 		assert(group_nmask <= BITMAP_GROUP_NBITS);
255*8e33eff8Schristos 		bitmap_t group_mask = ~((1LU << group_nmask) - 1);
256*8e33eff8Schristos 		bitmap_t group_masked = group & group_mask;
257*8e33eff8Schristos 		if (group_masked == 0LU) {
258*8e33eff8Schristos 			if (group == 0LU) {
259*8e33eff8Schristos 				return binfo->nbits;
260*8e33eff8Schristos 			}
261*8e33eff8Schristos 			/*
262*8e33eff8Schristos 			 * min_bit was preceded by one or more unset bits in
263*8e33eff8Schristos 			 * this group, but there are no other unset bits in this
264*8e33eff8Schristos 			 * group.  Try again starting at the first bit of the
265*8e33eff8Schristos 			 * next sibling.  This will recurse at most once per
266*8e33eff8Schristos 			 * non-root level.
267*8e33eff8Schristos 			 */
268*8e33eff8Schristos 			size_t sib_base = bit + (ZU(1) << lg_bits_per_group);
269*8e33eff8Schristos 			assert(sib_base > min_bit);
270*8e33eff8Schristos 			assert(sib_base > bit);
271*8e33eff8Schristos 			if (sib_base >= binfo->nbits) {
272*8e33eff8Schristos 				return binfo->nbits;
273*8e33eff8Schristos 			}
274*8e33eff8Schristos 			return bitmap_ffu(bitmap, binfo, sib_base);
275*8e33eff8Schristos 		}
276*8e33eff8Schristos 		bit += ((size_t)(ffs_lu(group_masked) - 1)) <<
277*8e33eff8Schristos 		    (lg_bits_per_group - LG_BITMAP_GROUP_NBITS);
278*8e33eff8Schristos 	}
279*8e33eff8Schristos 	assert(bit >= min_bit);
280*8e33eff8Schristos 	assert(bit < binfo->nbits);
281*8e33eff8Schristos 	return bit;
282*8e33eff8Schristos #else
283*8e33eff8Schristos 	size_t i = min_bit >> LG_BITMAP_GROUP_NBITS;
284*8e33eff8Schristos 	bitmap_t g = bitmap[i] & ~((1LU << (min_bit & BITMAP_GROUP_NBITS_MASK))
285*8e33eff8Schristos 	    - 1);
286*8e33eff8Schristos 	size_t bit;
287*8e33eff8Schristos 	do {
288*8e33eff8Schristos 		bit = ffs_lu(g);
289*8e33eff8Schristos 		if (bit != 0) {
290*8e33eff8Schristos 			return (i << LG_BITMAP_GROUP_NBITS) + (bit - 1);
291*8e33eff8Schristos 		}
292*8e33eff8Schristos 		i++;
293*8e33eff8Schristos 		g = bitmap[i];
294*8e33eff8Schristos 	} while (i < binfo->ngroups);
295*8e33eff8Schristos 	return binfo->nbits;
296*8e33eff8Schristos #endif
297*8e33eff8Schristos }
298*8e33eff8Schristos 
299*8e33eff8Schristos /* sfu: set first unset. */
300*8e33eff8Schristos static inline size_t
301*8e33eff8Schristos bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo) {
302*8e33eff8Schristos 	size_t bit;
303*8e33eff8Schristos 	bitmap_t g;
304*8e33eff8Schristos 	unsigned i;
305*8e33eff8Schristos 
306*8e33eff8Schristos 	assert(!bitmap_full(bitmap, binfo));
307*8e33eff8Schristos 
308*8e33eff8Schristos #ifdef BITMAP_USE_TREE
309*8e33eff8Schristos 	i = binfo->nlevels - 1;
310*8e33eff8Schristos 	g = bitmap[binfo->levels[i].group_offset];
311*8e33eff8Schristos 	bit = ffs_lu(g) - 1;
312*8e33eff8Schristos 	while (i > 0) {
313*8e33eff8Schristos 		i--;
314*8e33eff8Schristos 		g = bitmap[binfo->levels[i].group_offset + bit];
315*8e33eff8Schristos 		bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffs_lu(g) - 1);
316*8e33eff8Schristos 	}
317*8e33eff8Schristos #else
318*8e33eff8Schristos 	i = 0;
319*8e33eff8Schristos 	g = bitmap[0];
320*8e33eff8Schristos 	while ((bit = ffs_lu(g)) == 0) {
321*8e33eff8Schristos 		i++;
322*8e33eff8Schristos 		g = bitmap[i];
323*8e33eff8Schristos 	}
324*8e33eff8Schristos 	bit = (i << LG_BITMAP_GROUP_NBITS) + (bit - 1);
325*8e33eff8Schristos #endif
326*8e33eff8Schristos 	bitmap_set(bitmap, binfo, bit);
327*8e33eff8Schristos 	return bit;
328*8e33eff8Schristos }
329*8e33eff8Schristos 
330*8e33eff8Schristos static inline void
331*8e33eff8Schristos bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
332*8e33eff8Schristos 	size_t goff;
333*8e33eff8Schristos 	bitmap_t *gp;
334*8e33eff8Schristos 	bitmap_t g;
335*8e33eff8Schristos 	UNUSED bool propagate;
336*8e33eff8Schristos 
337*8e33eff8Schristos 	assert(bit < binfo->nbits);
338*8e33eff8Schristos 	assert(bitmap_get(bitmap, binfo, bit));
339*8e33eff8Schristos 	goff = bit >> LG_BITMAP_GROUP_NBITS;
340*8e33eff8Schristos 	gp = &bitmap[goff];
341*8e33eff8Schristos 	g = *gp;
342*8e33eff8Schristos 	propagate = (g == 0);
343*8e33eff8Schristos 	assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
344*8e33eff8Schristos 	g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
345*8e33eff8Schristos 	*gp = g;
346*8e33eff8Schristos 	assert(!bitmap_get(bitmap, binfo, bit));
347*8e33eff8Schristos #ifdef BITMAP_USE_TREE
348*8e33eff8Schristos 	/* Propagate group state transitions up the tree. */
349*8e33eff8Schristos 	if (propagate) {
350*8e33eff8Schristos 		unsigned i;
351*8e33eff8Schristos 		for (i = 1; i < binfo->nlevels; i++) {
352*8e33eff8Schristos 			bit = goff;
353*8e33eff8Schristos 			goff = bit >> LG_BITMAP_GROUP_NBITS;
354*8e33eff8Schristos 			gp = &bitmap[binfo->levels[i].group_offset + goff];
355*8e33eff8Schristos 			g = *gp;
356*8e33eff8Schristos 			propagate = (g == 0);
357*8e33eff8Schristos 			assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)))
358*8e33eff8Schristos 			    == 0);
359*8e33eff8Schristos 			g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
360*8e33eff8Schristos 			*gp = g;
361*8e33eff8Schristos 			if (!propagate) {
362*8e33eff8Schristos 				break;
363*8e33eff8Schristos 			}
364*8e33eff8Schristos 		}
365*8e33eff8Schristos 	}
366*8e33eff8Schristos #endif /* BITMAP_USE_TREE */
367*8e33eff8Schristos }
368*8e33eff8Schristos 
369*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_BITMAP_H */
370