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