1a4bd5210SJason Evans #define JEMALLOC_BITMAP_C_ 2*b7eaed25SJason Evans #include "jemalloc/internal/jemalloc_preamble.h" 3*b7eaed25SJason Evans #include "jemalloc/internal/jemalloc_internal_includes.h" 4*b7eaed25SJason Evans 5*b7eaed25SJason Evans #include "jemalloc/internal/assert.h" 6a4bd5210SJason Evans 7a4bd5210SJason Evans /******************************************************************************/ 8a4bd5210SJason Evans 9*b7eaed25SJason Evans #ifdef BITMAP_USE_TREE 10df0d881dSJason Evans 11a4bd5210SJason Evans void 12*b7eaed25SJason Evans bitmap_info_init(bitmap_info_t *binfo, size_t nbits) { 13a4bd5210SJason Evans unsigned i; 14a4bd5210SJason Evans size_t group_count; 15a4bd5210SJason Evans 16a4bd5210SJason Evans assert(nbits > 0); 17a4bd5210SJason Evans assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 18a4bd5210SJason Evans 19a4bd5210SJason Evans /* 20a4bd5210SJason Evans * Compute the number of groups necessary to store nbits bits, and 21a4bd5210SJason Evans * progressively work upward through the levels until reaching a level 22a4bd5210SJason Evans * that requires only one group. 23a4bd5210SJason Evans */ 24a4bd5210SJason Evans binfo->levels[0].group_offset = 0; 25d0e79aa3SJason Evans group_count = BITMAP_BITS2GROUPS(nbits); 26a4bd5210SJason Evans for (i = 1; group_count > 1; i++) { 27a4bd5210SJason Evans assert(i < BITMAP_MAX_LEVELS); 28a4bd5210SJason Evans binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 29a4bd5210SJason Evans + group_count; 30d0e79aa3SJason Evans group_count = BITMAP_BITS2GROUPS(group_count); 31a4bd5210SJason Evans } 32a4bd5210SJason Evans binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 33a4bd5210SJason Evans + group_count; 34d0e79aa3SJason Evans assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX); 35a4bd5210SJason Evans binfo->nlevels = i; 36a4bd5210SJason Evans binfo->nbits = nbits; 37a4bd5210SJason Evans } 38a4bd5210SJason Evans 39df0d881dSJason Evans static size_t 40*b7eaed25SJason Evans bitmap_info_ngroups(const bitmap_info_t *binfo) { 41*b7eaed25SJason Evans return binfo->levels[binfo->nlevels].group_offset; 42a4bd5210SJason Evans } 43a4bd5210SJason Evans 44a4bd5210SJason Evans void 45*b7eaed25SJason Evans bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo, bool fill) { 46a4bd5210SJason Evans size_t extra; 47a4bd5210SJason Evans unsigned i; 48a4bd5210SJason Evans 49a4bd5210SJason Evans /* 50a4bd5210SJason Evans * Bits are actually inverted with regard to the external bitmap 51*b7eaed25SJason Evans * interface. 52*b7eaed25SJason Evans */ 53*b7eaed25SJason Evans 54*b7eaed25SJason Evans if (fill) { 55*b7eaed25SJason Evans /* The "filled" bitmap starts out with all 0 bits. */ 56*b7eaed25SJason Evans memset(bitmap, 0, bitmap_size(binfo)); 57*b7eaed25SJason Evans return; 58*b7eaed25SJason Evans } 59*b7eaed25SJason Evans 60*b7eaed25SJason Evans /* 61*b7eaed25SJason Evans * The "empty" bitmap starts out with all 1 bits, except for trailing 62*b7eaed25SJason Evans * unused bits (if any). Note that each group uses bit 0 to correspond 63*b7eaed25SJason Evans * to the first logical bit in the group, so extra bits are the most 64*b7eaed25SJason Evans * significant bits of the last group. 65a4bd5210SJason Evans */ 66df0d881dSJason Evans memset(bitmap, 0xffU, bitmap_size(binfo)); 67a4bd5210SJason Evans extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 68a4bd5210SJason Evans & BITMAP_GROUP_NBITS_MASK; 69*b7eaed25SJason Evans if (extra != 0) { 70a4bd5210SJason Evans bitmap[binfo->levels[1].group_offset - 1] >>= extra; 71*b7eaed25SJason Evans } 72a4bd5210SJason Evans for (i = 1; i < binfo->nlevels; i++) { 73a4bd5210SJason Evans size_t group_count = binfo->levels[i].group_offset - 74a4bd5210SJason Evans binfo->levels[i-1].group_offset; 75a4bd5210SJason Evans extra = (BITMAP_GROUP_NBITS - (group_count & 76a4bd5210SJason Evans BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; 77*b7eaed25SJason Evans if (extra != 0) { 78a4bd5210SJason Evans bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; 79a4bd5210SJason Evans } 80a4bd5210SJason Evans } 81*b7eaed25SJason Evans } 82df0d881dSJason Evans 83*b7eaed25SJason Evans #else /* BITMAP_USE_TREE */ 84df0d881dSJason Evans 85df0d881dSJason Evans void 86*b7eaed25SJason Evans bitmap_info_init(bitmap_info_t *binfo, size_t nbits) { 87df0d881dSJason Evans assert(nbits > 0); 88df0d881dSJason Evans assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 89df0d881dSJason Evans 901f0a49e8SJason Evans binfo->ngroups = BITMAP_BITS2GROUPS(nbits); 91df0d881dSJason Evans binfo->nbits = nbits; 92df0d881dSJason Evans } 93df0d881dSJason Evans 94df0d881dSJason Evans static size_t 95*b7eaed25SJason Evans bitmap_info_ngroups(const bitmap_info_t *binfo) { 96*b7eaed25SJason Evans return binfo->ngroups; 97df0d881dSJason Evans } 98df0d881dSJason Evans 99df0d881dSJason Evans void 100*b7eaed25SJason Evans bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo, bool fill) { 101df0d881dSJason Evans size_t extra; 102df0d881dSJason Evans 103*b7eaed25SJason Evans if (fill) { 104*b7eaed25SJason Evans memset(bitmap, 0, bitmap_size(binfo)); 105*b7eaed25SJason Evans return; 106*b7eaed25SJason Evans } 107*b7eaed25SJason Evans 108df0d881dSJason Evans memset(bitmap, 0xffU, bitmap_size(binfo)); 1091f0a49e8SJason Evans extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 1101f0a49e8SJason Evans & BITMAP_GROUP_NBITS_MASK; 111*b7eaed25SJason Evans if (extra != 0) { 1121f0a49e8SJason Evans bitmap[binfo->ngroups - 1] >>= extra; 113df0d881dSJason Evans } 114*b7eaed25SJason Evans } 115df0d881dSJason Evans 116*b7eaed25SJason Evans #endif /* BITMAP_USE_TREE */ 117df0d881dSJason Evans 118df0d881dSJason Evans size_t 119*b7eaed25SJason Evans bitmap_size(const bitmap_info_t *binfo) { 120df0d881dSJason Evans return (bitmap_info_ngroups(binfo) << LG_SIZEOF_BITMAP); 121df0d881dSJason Evans } 122