blob: 17efb73c12c037113cad2360c1388fded24a8b4c [file] [log] [blame]
Jason Evansc0cc5db2017-01-19 21:41:41 -08001#define JEMALLOC_BITMAP_C_
Jason Evans84c8eef2011-03-16 10:30:13 -07002#include "jemalloc/internal/jemalloc_internal.h"
3
4/******************************************************************************/
Jason Evans84c8eef2011-03-16 10:30:13 -07005
Jason Evansb6837342016-04-06 18:30:02 -07006#ifdef BITMAP_USE_TREE
Dave Watsonb8823ab2016-02-24 08:04:43 -08007
Jason Evans84c8eef2011-03-16 10:30:13 -07008void
Jason Evansc4c25922017-01-15 16:56:30 -08009bitmap_info_init(bitmap_info_t *binfo, size_t nbits) {
Jason Evans84c8eef2011-03-16 10:30:13 -070010 unsigned i;
11 size_t group_count;
12
13 assert(nbits > 0);
14 assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS));
15
16 /*
17 * Compute the number of groups necessary to store nbits bits, and
18 * progressively work upward through the levels until reaching a level
19 * that requires only one group.
20 */
21 binfo->levels[0].group_offset = 0;
Jason Evansf97e5ac2014-09-28 14:43:11 -070022 group_count = BITMAP_BITS2GROUPS(nbits);
Jason Evans84c8eef2011-03-16 10:30:13 -070023 for (i = 1; group_count > 1; i++) {
24 assert(i < BITMAP_MAX_LEVELS);
25 binfo->levels[i].group_offset = binfo->levels[i-1].group_offset
26 + group_count;
Jason Evansf97e5ac2014-09-28 14:43:11 -070027 group_count = BITMAP_BITS2GROUPS(group_count);
Jason Evans84c8eef2011-03-16 10:30:13 -070028 }
29 binfo->levels[i].group_offset = binfo->levels[i-1].group_offset
30 + group_count;
Jason Evansf97e5ac2014-09-28 14:43:11 -070031 assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX);
Jason Evans84c8eef2011-03-16 10:30:13 -070032 binfo->nlevels = i;
33 binfo->nbits = nbits;
34}
35
Dave Watsonb8823ab2016-02-24 08:04:43 -080036static size_t
Jason Evansc4c25922017-01-15 16:56:30 -080037bitmap_info_ngroups(const bitmap_info_t *binfo) {
Jason Evansf4086432017-01-19 18:15:45 -080038 return binfo->levels[binfo->nlevels].group_offset;
Dave Watsonb8823ab2016-02-24 08:04:43 -080039}
40
Jason Evans84c8eef2011-03-16 10:30:13 -070041void
Jason Evansc4c25922017-01-15 16:56:30 -080042bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) {
Jason Evans84c8eef2011-03-16 10:30:13 -070043 size_t extra;
44 unsigned i;
45
46 /*
47 * Bits are actually inverted with regard to the external bitmap
48 * interface, so the bitmap starts out with all 1 bits, except for
49 * trailing unused bits (if any). Note that each group uses bit 0 to
50 * correspond to the first logical bit in the group, so extra bits
51 * are the most significant bits of the last group.
52 */
Jason Evans01ecdf32016-02-26 13:59:41 -080053 memset(bitmap, 0xffU, bitmap_size(binfo));
Jason Evans84c8eef2011-03-16 10:30:13 -070054 extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK))
55 & BITMAP_GROUP_NBITS_MASK;
Jason Evansc4c25922017-01-15 16:56:30 -080056 if (extra != 0) {
Jason Evans84c8eef2011-03-16 10:30:13 -070057 bitmap[binfo->levels[1].group_offset - 1] >>= extra;
Jason Evansc4c25922017-01-15 16:56:30 -080058 }
Jason Evans84c8eef2011-03-16 10:30:13 -070059 for (i = 1; i < binfo->nlevels; i++) {
60 size_t group_count = binfo->levels[i].group_offset -
61 binfo->levels[i-1].group_offset;
62 extra = (BITMAP_GROUP_NBITS - (group_count &
63 BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK;
Jason Evansc4c25922017-01-15 16:56:30 -080064 if (extra != 0) {
Jason Evans84c8eef2011-03-16 10:30:13 -070065 bitmap[binfo->levels[i+1].group_offset - 1] >>= extra;
Jason Evansc4c25922017-01-15 16:56:30 -080066 }
Jason Evans84c8eef2011-03-16 10:30:13 -070067 }
68}
Jason Evans01ecdf32016-02-26 13:59:41 -080069
Jason Evansb6837342016-04-06 18:30:02 -070070#else /* BITMAP_USE_TREE */
Dave Watsonb8823ab2016-02-24 08:04:43 -080071
72void
Jason Evansc4c25922017-01-15 16:56:30 -080073bitmap_info_init(bitmap_info_t *binfo, size_t nbits) {
Dave Watsonb8823ab2016-02-24 08:04:43 -080074 assert(nbits > 0);
75 assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS));
76
Jason Evans2ee2f1e2016-04-06 10:38:47 -070077 binfo->ngroups = BITMAP_BITS2GROUPS(nbits);
Dave Watsonb8823ab2016-02-24 08:04:43 -080078 binfo->nbits = nbits;
79}
80
Jason Evans01ecdf32016-02-26 13:59:41 -080081static size_t
Jason Evansc4c25922017-01-15 16:56:30 -080082bitmap_info_ngroups(const bitmap_info_t *binfo) {
Jason Evansf4086432017-01-19 18:15:45 -080083 return binfo->ngroups;
Jason Evans01ecdf32016-02-26 13:59:41 -080084}
85
Dave Watsonb8823ab2016-02-24 08:04:43 -080086void
Jason Evansc4c25922017-01-15 16:56:30 -080087bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) {
Dave Watsonb8823ab2016-02-24 08:04:43 -080088 size_t extra;
89
90 memset(bitmap, 0xffU, bitmap_size(binfo));
Jason Evans2ee2f1e2016-04-06 10:38:47 -070091 extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK))
92 & BITMAP_GROUP_NBITS_MASK;
Jason Evansc4c25922017-01-15 16:56:30 -080093 if (extra != 0) {
Jason Evans2ee2f1e2016-04-06 10:38:47 -070094 bitmap[binfo->ngroups - 1] >>= extra;
Jason Evansc4c25922017-01-15 16:56:30 -080095 }
Dave Watsonb8823ab2016-02-24 08:04:43 -080096}
97
Jason Evansb6837342016-04-06 18:30:02 -070098#endif /* BITMAP_USE_TREE */
Dave Watsonb8823ab2016-02-24 08:04:43 -080099
Jason Evans01ecdf32016-02-26 13:59:41 -0800100size_t
Jason Evansc4c25922017-01-15 16:56:30 -0800101bitmap_size(const bitmap_info_t *binfo) {
Jason Evans01ecdf32016-02-26 13:59:41 -0800102 return (bitmap_info_ngroups(binfo) << LG_SIZEOF_BITMAP);
103}