Blame memkind-1.10.1/jemalloc/include/jemalloc/internal/bitmap.h

Packit Service 7f3b24
#ifndef JEMALLOC_INTERNAL_BITMAP_H
Packit Service 7f3b24
#define JEMALLOC_INTERNAL_BITMAP_H
Packit Service 7f3b24
Packit Service 7f3b24
#include "jemalloc/internal/arena_types.h"
Packit Service 7f3b24
#include "jemalloc/internal/bit_util.h"
Packit Service 7f3b24
#include "jemalloc/internal/sc.h"
Packit Service 7f3b24
Packit Service 7f3b24
typedef unsigned long bitmap_t;
Packit Service 7f3b24
#define LG_SIZEOF_BITMAP	LG_SIZEOF_LONG
Packit Service 7f3b24
Packit Service 7f3b24
/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
Packit Service 7f3b24
#if LG_SLAB_MAXREGS > LG_CEIL(SC_NSIZES)
Packit Service 7f3b24
/* Maximum bitmap bit count is determined by maximum regions per slab. */
Packit Service 7f3b24
#  define LG_BITMAP_MAXBITS	LG_SLAB_MAXREGS
Packit Service 7f3b24
#else
Packit Service 7f3b24
/* Maximum bitmap bit count is determined by number of extent size classes. */
Packit Service 7f3b24
#  define LG_BITMAP_MAXBITS	LG_CEIL(SC_NSIZES)
Packit Service 7f3b24
#endif
Packit Service 7f3b24
#define BITMAP_MAXBITS		(ZU(1) << LG_BITMAP_MAXBITS)
Packit Service 7f3b24
Packit Service 7f3b24
/* Number of bits per group. */
Packit Service 7f3b24
#define LG_BITMAP_GROUP_NBITS		(LG_SIZEOF_BITMAP + 3)
Packit Service 7f3b24
#define BITMAP_GROUP_NBITS		(1U << LG_BITMAP_GROUP_NBITS)
Packit Service 7f3b24
#define BITMAP_GROUP_NBITS_MASK		(BITMAP_GROUP_NBITS-1)
Packit Service 7f3b24
Packit Service 7f3b24
/*
Packit Service 7f3b24
 * Do some analysis on how big the bitmap is before we use a tree.  For a brute
Packit Service 7f3b24
 * force linear search, if we would have to call ffs_lu() more than 2^3 times,
Packit Service 7f3b24
 * use a tree instead.
Packit Service 7f3b24
 */
Packit Service 7f3b24
#if LG_BITMAP_MAXBITS - LG_BITMAP_GROUP_NBITS > 3
Packit Service 7f3b24
#  define BITMAP_USE_TREE
Packit Service 7f3b24
#endif
Packit Service 7f3b24
Packit Service 7f3b24
/* Number of groups required to store a given number of bits. */
Packit Service 7f3b24
#define BITMAP_BITS2GROUPS(nbits)					\
Packit Service 7f3b24
    (((nbits) + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS)
Packit Service 7f3b24
Packit Service 7f3b24
/*
Packit Service 7f3b24
 * Number of groups required at a particular level for a given number of bits.
Packit Service 7f3b24
 */
Packit Service 7f3b24
#define BITMAP_GROUPS_L0(nbits)						\
Packit Service 7f3b24
    BITMAP_BITS2GROUPS(nbits)
Packit Service 7f3b24
#define BITMAP_GROUPS_L1(nbits)						\
Packit Service 7f3b24
    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits))
Packit Service 7f3b24
#define BITMAP_GROUPS_L2(nbits)						\
Packit Service 7f3b24
    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))
Packit Service 7f3b24
#define BITMAP_GROUPS_L3(nbits)						\
Packit Service 7f3b24
    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(		\
Packit Service 7f3b24
	BITMAP_BITS2GROUPS((nbits)))))
Packit Service 7f3b24
#define BITMAP_GROUPS_L4(nbits)						\
Packit Service 7f3b24
    BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(		\
Packit Service 7f3b24
	BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))))
Packit Service 7f3b24
Packit Service 7f3b24
/*
Packit Service 7f3b24
 * Assuming the number of levels, number of groups required for a given number
Packit Service 7f3b24
 * of bits.
Packit Service 7f3b24
 */
Packit Service 7f3b24
#define BITMAP_GROUPS_1_LEVEL(nbits)					\
Packit Service 7f3b24
    BITMAP_GROUPS_L0(nbits)
Packit Service 7f3b24
#define BITMAP_GROUPS_2_LEVEL(nbits)					\
Packit Service 7f3b24
    (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits))
Packit Service 7f3b24
#define BITMAP_GROUPS_3_LEVEL(nbits)					\
Packit Service 7f3b24
    (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits))
Packit Service 7f3b24
#define BITMAP_GROUPS_4_LEVEL(nbits)					\
Packit Service 7f3b24
    (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits))
Packit Service 7f3b24
#define BITMAP_GROUPS_5_LEVEL(nbits)					\
Packit Service 7f3b24
    (BITMAP_GROUPS_4_LEVEL(nbits) + BITMAP_GROUPS_L4(nbits))
Packit Service 7f3b24
Packit Service 7f3b24
/*
Packit Service 7f3b24
 * Maximum number of groups required to support LG_BITMAP_MAXBITS.
Packit Service 7f3b24
 */
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
Packit Service 7f3b24
#if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS
Packit Service 7f3b24
#  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_1_LEVEL(nbits)
Packit Service 7f3b24
#  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS)
Packit Service 7f3b24
#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2
Packit Service 7f3b24
#  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_2_LEVEL(nbits)
Packit Service 7f3b24
#  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS)
Packit Service 7f3b24
#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3
Packit Service 7f3b24
#  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_3_LEVEL(nbits)
Packit Service 7f3b24
#  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS)
Packit Service 7f3b24
#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4
Packit Service 7f3b24
#  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_4_LEVEL(nbits)
Packit Service 7f3b24
#  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS)
Packit Service 7f3b24
#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 5
Packit Service 7f3b24
#  define BITMAP_GROUPS(nbits)	BITMAP_GROUPS_5_LEVEL(nbits)
Packit Service 7f3b24
#  define BITMAP_GROUPS_MAX	BITMAP_GROUPS_5_LEVEL(BITMAP_MAXBITS)
Packit Service 7f3b24
#else
Packit Service 7f3b24
#  error "Unsupported bitmap size"
Packit Service 7f3b24
#endif
Packit Service 7f3b24
Packit Service 7f3b24
/*
Packit Service 7f3b24
 * Maximum number of levels possible.  This could be statically computed based
Packit Service 7f3b24
 * on LG_BITMAP_MAXBITS:
Packit Service 7f3b24
 *
Packit Service 7f3b24
 * #define BITMAP_MAX_LEVELS \
Packit Service 7f3b24
 *     (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \
Packit Service 7f3b24
 *     + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
Packit Service 7f3b24
 *
Packit Service 7f3b24
 * However, that would not allow the generic BITMAP_INFO_INITIALIZER() macro, so
Packit Service 7f3b24
 * instead hardcode BITMAP_MAX_LEVELS to the largest number supported by the
Packit Service 7f3b24
 * various cascading macros.  The only additional cost this incurs is some
Packit Service 7f3b24
 * unused trailing entries in bitmap_info_t structures; the bitmaps themselves
Packit Service 7f3b24
 * are not impacted.
Packit Service 7f3b24
 */
Packit Service 7f3b24
#define BITMAP_MAX_LEVELS	5
Packit Service 7f3b24
Packit Service 7f3b24
#define BITMAP_INFO_INITIALIZER(nbits) {				\
Packit Service 7f3b24
	/* nbits. */							\
Packit Service 7f3b24
	nbits,								\
Packit Service 7f3b24
	/* nlevels. */							\
Packit Service 7f3b24
	(BITMAP_GROUPS_L0(nbits) > BITMAP_GROUPS_L1(nbits)) +		\
Packit Service 7f3b24
	    (BITMAP_GROUPS_L1(nbits) > BITMAP_GROUPS_L2(nbits)) +	\
Packit Service 7f3b24
	    (BITMAP_GROUPS_L2(nbits) > BITMAP_GROUPS_L3(nbits)) +	\
Packit Service 7f3b24
	    (BITMAP_GROUPS_L3(nbits) > BITMAP_GROUPS_L4(nbits)) + 1,	\
Packit Service 7f3b24
	/* levels. */							\
Packit Service 7f3b24
	{								\
Packit Service 7f3b24
		{0},							\
Packit Service 7f3b24
		{BITMAP_GROUPS_L0(nbits)},				\
Packit Service 7f3b24
		{BITMAP_GROUPS_L1(nbits) + BITMAP_GROUPS_L0(nbits)},	\
Packit Service 7f3b24
		{BITMAP_GROUPS_L2(nbits) + BITMAP_GROUPS_L1(nbits) +	\
Packit Service 7f3b24
		    BITMAP_GROUPS_L0(nbits)},				\
Packit Service 7f3b24
		{BITMAP_GROUPS_L3(nbits) + BITMAP_GROUPS_L2(nbits) +	\
Packit Service 7f3b24
		    BITMAP_GROUPS_L1(nbits) + BITMAP_GROUPS_L0(nbits)},	\
Packit Service 7f3b24
		{BITMAP_GROUPS_L4(nbits) + BITMAP_GROUPS_L3(nbits) +	\
Packit Service 7f3b24
		     BITMAP_GROUPS_L2(nbits) + BITMAP_GROUPS_L1(nbits)	\
Packit Service 7f3b24
		     + BITMAP_GROUPS_L0(nbits)}				\
Packit Service 7f3b24
	}								\
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
#else /* BITMAP_USE_TREE */
Packit Service 7f3b24
Packit Service 7f3b24
#define BITMAP_GROUPS(nbits)	BITMAP_BITS2GROUPS(nbits)
Packit Service 7f3b24
#define BITMAP_GROUPS_MAX	BITMAP_BITS2GROUPS(BITMAP_MAXBITS)
Packit Service 7f3b24
Packit Service 7f3b24
#define BITMAP_INFO_INITIALIZER(nbits) {				\
Packit Service 7f3b24
	/* nbits. */							\
Packit Service 7f3b24
	nbits,								\
Packit Service 7f3b24
	/* ngroups. */							\
Packit Service 7f3b24
	BITMAP_BITS2GROUPS(nbits)					\
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
#endif /* BITMAP_USE_TREE */
Packit Service 7f3b24
Packit Service 7f3b24
typedef struct bitmap_level_s {
Packit Service 7f3b24
	/* Offset of this level's groups within the array of groups. */
Packit Service 7f3b24
	size_t group_offset;
Packit Service 7f3b24
} bitmap_level_t;
Packit Service 7f3b24
Packit Service 7f3b24
typedef struct bitmap_info_s {
Packit Service 7f3b24
	/* Logical number of bits in bitmap (stored at bottom level). */
Packit Service 7f3b24
	size_t nbits;
Packit Service 7f3b24
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	/* Number of levels necessary for nbits. */
Packit Service 7f3b24
	unsigned nlevels;
Packit Service 7f3b24
Packit Service 7f3b24
	/*
Packit Service 7f3b24
	 * Only the first (nlevels+1) elements are used, and levels are ordered
Packit Service 7f3b24
	 * bottom to top (e.g. the bottom level is stored in levels[0]).
Packit Service 7f3b24
	 */
Packit Service 7f3b24
	bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
Packit Service 7f3b24
#else /* BITMAP_USE_TREE */
Packit Service 7f3b24
	/* Number of groups necessary for nbits. */
Packit Service 7f3b24
	size_t ngroups;
Packit Service 7f3b24
#endif /* BITMAP_USE_TREE */
Packit Service 7f3b24
} bitmap_info_t;
Packit Service 7f3b24
Packit Service 7f3b24
void bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
Packit Service 7f3b24
void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo, bool fill);
Packit Service 7f3b24
size_t bitmap_size(const bitmap_info_t *binfo);
Packit Service 7f3b24
Packit Service 7f3b24
static inline bool
Packit Service 7f3b24
bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo) {
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	size_t rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
Packit Service 7f3b24
	bitmap_t rg = bitmap[rgoff];
Packit Service 7f3b24
	/* The bitmap is full iff the root group is 0. */
Packit Service 7f3b24
	return (rg == 0);
Packit Service 7f3b24
#else
Packit Service 7f3b24
	size_t i;
Packit Service 7f3b24
Packit Service 7f3b24
	for (i = 0; i < binfo->ngroups; i++) {
Packit Service 7f3b24
		if (bitmap[i] != 0) {
Packit Service 7f3b24
			return false;
Packit Service 7f3b24
		}
Packit Service 7f3b24
	}
Packit Service 7f3b24
	return true;
Packit Service 7f3b24
#endif
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static inline bool
Packit Service 7f3b24
bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
Packit Service 7f3b24
	size_t goff;
Packit Service 7f3b24
	bitmap_t g;
Packit Service 7f3b24
Packit Service 7f3b24
	assert(bit < binfo->nbits);
Packit Service 7f3b24
	goff = bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
	g = bitmap[goff];
Packit Service 7f3b24
	return !(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static inline void
Packit Service 7f3b24
bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
Packit Service 7f3b24
	size_t goff;
Packit Service 7f3b24
	bitmap_t *gp;
Packit Service 7f3b24
	bitmap_t g;
Packit Service 7f3b24
Packit Service 7f3b24
	assert(bit < binfo->nbits);
Packit Service 7f3b24
	assert(!bitmap_get(bitmap, binfo, bit));
Packit Service 7f3b24
	goff = bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
	gp = &bitmap[goff];
Packit Service 7f3b24
	g = *gp;
Packit Service 7f3b24
	assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
Packit Service 7f3b24
	g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
Packit Service 7f3b24
	*gp = g;
Packit Service 7f3b24
	assert(bitmap_get(bitmap, binfo, bit));
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	/* Propagate group state transitions up the tree. */
Packit Service 7f3b24
	if (g == 0) {
Packit Service 7f3b24
		unsigned i;
Packit Service 7f3b24
		for (i = 1; i < binfo->nlevels; i++) {
Packit Service 7f3b24
			bit = goff;
Packit Service 7f3b24
			goff = bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
			gp = &bitmap[binfo->levels[i].group_offset + goff];
Packit Service 7f3b24
			g = *gp;
Packit Service 7f3b24
			assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
Packit Service 7f3b24
			g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
Packit Service 7f3b24
			*gp = g;
Packit Service 7f3b24
			if (g != 0) {
Packit Service 7f3b24
				break;
Packit Service 7f3b24
			}
Packit Service 7f3b24
		}
Packit Service 7f3b24
	}
Packit Service 7f3b24
#endif
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
/* ffu: find first unset >= bit. */
Packit Service 7f3b24
static inline size_t
Packit Service 7f3b24
bitmap_ffu(const bitmap_t *bitmap, const bitmap_info_t *binfo, size_t min_bit) {
Packit Service 7f3b24
	assert(min_bit < binfo->nbits);
Packit Service 7f3b24
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	size_t bit = 0;
Packit Service 7f3b24
	for (unsigned level = binfo->nlevels; level--;) {
Packit Service 7f3b24
		size_t lg_bits_per_group = (LG_BITMAP_GROUP_NBITS * (level +
Packit Service 7f3b24
		    1));
Packit Service 7f3b24
		bitmap_t group = bitmap[binfo->levels[level].group_offset + (bit
Packit Service 7f3b24
		    >> lg_bits_per_group)];
Packit Service 7f3b24
		unsigned group_nmask = (unsigned)(((min_bit > bit) ? (min_bit -
Packit Service 7f3b24
		    bit) : 0) >> (lg_bits_per_group - LG_BITMAP_GROUP_NBITS));
Packit Service 7f3b24
		assert(group_nmask <= BITMAP_GROUP_NBITS);
Packit Service 7f3b24
		bitmap_t group_mask = ~((1LU << group_nmask) - 1);
Packit Service 7f3b24
		bitmap_t group_masked = group & group_mask;
Packit Service 7f3b24
		if (group_masked == 0LU) {
Packit Service 7f3b24
			if (group == 0LU) {
Packit Service 7f3b24
				return binfo->nbits;
Packit Service 7f3b24
			}
Packit Service 7f3b24
			/*
Packit Service 7f3b24
			 * min_bit was preceded by one or more unset bits in
Packit Service 7f3b24
			 * this group, but there are no other unset bits in this
Packit Service 7f3b24
			 * group.  Try again starting at the first bit of the
Packit Service 7f3b24
			 * next sibling.  This will recurse at most once per
Packit Service 7f3b24
			 * non-root level.
Packit Service 7f3b24
			 */
Packit Service 7f3b24
			size_t sib_base = bit + (ZU(1) << lg_bits_per_group);
Packit Service 7f3b24
			assert(sib_base > min_bit);
Packit Service 7f3b24
			assert(sib_base > bit);
Packit Service 7f3b24
			if (sib_base >= binfo->nbits) {
Packit Service 7f3b24
				return binfo->nbits;
Packit Service 7f3b24
			}
Packit Service 7f3b24
			return bitmap_ffu(bitmap, binfo, sib_base);
Packit Service 7f3b24
		}
Packit Service 7f3b24
		bit += ((size_t)(ffs_lu(group_masked) - 1)) <<
Packit Service 7f3b24
		    (lg_bits_per_group - LG_BITMAP_GROUP_NBITS);
Packit Service 7f3b24
	}
Packit Service 7f3b24
	assert(bit >= min_bit);
Packit Service 7f3b24
	assert(bit < binfo->nbits);
Packit Service 7f3b24
	return bit;
Packit Service 7f3b24
#else
Packit Service 7f3b24
	size_t i = min_bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
	bitmap_t g = bitmap[i] & ~((1LU << (min_bit & BITMAP_GROUP_NBITS_MASK))
Packit Service 7f3b24
	    - 1);
Packit Service 7f3b24
	size_t bit;
Packit Service 7f3b24
	do {
Packit Service 7f3b24
		bit = ffs_lu(g);
Packit Service 7f3b24
		if (bit != 0) {
Packit Service 7f3b24
			return (i << LG_BITMAP_GROUP_NBITS) + (bit - 1);
Packit Service 7f3b24
		}
Packit Service 7f3b24
		i++;
Packit Service 7f3b24
		g = bitmap[i];
Packit Service 7f3b24
	} while (i < binfo->ngroups);
Packit Service 7f3b24
	return binfo->nbits;
Packit Service 7f3b24
#endif
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
/* sfu: set first unset. */
Packit Service 7f3b24
static inline size_t
Packit Service 7f3b24
bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo) {
Packit Service 7f3b24
	size_t bit;
Packit Service 7f3b24
	bitmap_t g;
Packit Service 7f3b24
	unsigned i;
Packit Service 7f3b24
Packit Service 7f3b24
	assert(!bitmap_full(bitmap, binfo));
Packit Service 7f3b24
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	i = binfo->nlevels - 1;
Packit Service 7f3b24
	g = bitmap[binfo->levels[i].group_offset];
Packit Service 7f3b24
	bit = ffs_lu(g) - 1;
Packit Service 7f3b24
	while (i > 0) {
Packit Service 7f3b24
		i--;
Packit Service 7f3b24
		g = bitmap[binfo->levels[i].group_offset + bit];
Packit Service 7f3b24
		bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffs_lu(g) - 1);
Packit Service 7f3b24
	}
Packit Service 7f3b24
#else
Packit Service 7f3b24
	i = 0;
Packit Service 7f3b24
	g = bitmap[0];
Packit Service 7f3b24
	while ((bit = ffs_lu(g)) == 0) {
Packit Service 7f3b24
		i++;
Packit Service 7f3b24
		g = bitmap[i];
Packit Service 7f3b24
	}
Packit Service 7f3b24
	bit = (i << LG_BITMAP_GROUP_NBITS) + (bit - 1);
Packit Service 7f3b24
#endif
Packit Service 7f3b24
	bitmap_set(bitmap, binfo, bit);
Packit Service 7f3b24
	return bit;
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
static inline void
Packit Service 7f3b24
bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) {
Packit Service 7f3b24
	size_t goff;
Packit Service 7f3b24
	bitmap_t *gp;
Packit Service 7f3b24
	bitmap_t g;
Packit Service 7f3b24
	UNUSED bool propagate;
Packit Service 7f3b24
Packit Service 7f3b24
	assert(bit < binfo->nbits);
Packit Service 7f3b24
	assert(bitmap_get(bitmap, binfo, bit));
Packit Service 7f3b24
	goff = bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
	gp = &bitmap[goff];
Packit Service 7f3b24
	g = *gp;
Packit Service 7f3b24
	propagate = (g == 0);
Packit Service 7f3b24
	assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
Packit Service 7f3b24
	g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
Packit Service 7f3b24
	*gp = g;
Packit Service 7f3b24
	assert(!bitmap_get(bitmap, binfo, bit));
Packit Service 7f3b24
#ifdef BITMAP_USE_TREE
Packit Service 7f3b24
	/* Propagate group state transitions up the tree. */
Packit Service 7f3b24
	if (propagate) {
Packit Service 7f3b24
		unsigned i;
Packit Service 7f3b24
		for (i = 1; i < binfo->nlevels; i++) {
Packit Service 7f3b24
			bit = goff;
Packit Service 7f3b24
			goff = bit >> LG_BITMAP_GROUP_NBITS;
Packit Service 7f3b24
			gp = &bitmap[binfo->levels[i].group_offset + goff];
Packit Service 7f3b24
			g = *gp;
Packit Service 7f3b24
			propagate = (g == 0);
Packit Service 7f3b24
			assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)))
Packit Service 7f3b24
			    == 0);
Packit Service 7f3b24
			g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
Packit Service 7f3b24
			*gp = g;
Packit Service 7f3b24
			if (!propagate) {
Packit Service 7f3b24
				break;
Packit Service 7f3b24
			}
Packit Service 7f3b24
		}
Packit Service 7f3b24
	}
Packit Service 7f3b24
#endif /* BITMAP_USE_TREE */
Packit Service 7f3b24
}
Packit Service 7f3b24
Packit Service 7f3b24
#endif /* JEMALLOC_INTERNAL_BITMAP_H */