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