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