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