]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/jemalloc/include/jemalloc/internal/bitmap.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / jemalloc / include / jemalloc / internal / bitmap.h
1 /******************************************************************************/
2 #ifdef JEMALLOC_H_TYPES
3
4 /* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */
5 #define LG_BITMAP_MAXBITS       LG_RUN_MAXREGS
6
7 typedef struct bitmap_level_s bitmap_level_t;
8 typedef struct bitmap_info_s bitmap_info_t;
9 typedef unsigned long bitmap_t;
10 #define LG_SIZEOF_BITMAP        LG_SIZEOF_LONG
11
12 /* Number of bits per group. */
13 #define LG_BITMAP_GROUP_NBITS           (LG_SIZEOF_BITMAP + 3)
14 #define BITMAP_GROUP_NBITS              (ZU(1) << LG_BITMAP_GROUP_NBITS)
15 #define BITMAP_GROUP_NBITS_MASK         (BITMAP_GROUP_NBITS-1)
16
17 /* Maximum number of levels possible. */
18 #define BITMAP_MAX_LEVELS                                               \
19     (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP)                              \
20     + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
21
22 #endif /* JEMALLOC_H_TYPES */
23 /******************************************************************************/
24 #ifdef JEMALLOC_H_STRUCTS
25
26 struct bitmap_level_s {
27         /* Offset of this level's groups within the array of groups. */
28         size_t group_offset;
29 };
30
31 struct bitmap_info_s {
32         /* Logical number of bits in bitmap (stored at bottom level). */
33         size_t nbits;
34
35         /* Number of levels necessary for nbits. */
36         unsigned nlevels;
37
38         /*
39          * Only the first (nlevels+1) elements are used, and levels are ordered
40          * bottom to top (e.g. the bottom level is stored in levels[0]).
41          */
42         bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
43 };
44
45 #endif /* JEMALLOC_H_STRUCTS */
46 /******************************************************************************/
47 #ifdef JEMALLOC_H_EXTERNS
48
49 void    bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
50 size_t  bitmap_info_ngroups(const bitmap_info_t *binfo);
51 size_t  bitmap_size(size_t nbits);
52 void    bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo);
53
54 #endif /* JEMALLOC_H_EXTERNS */
55 /******************************************************************************/
56 #ifdef JEMALLOC_H_INLINES
57
58 #ifndef JEMALLOC_ENABLE_INLINE
59 bool    bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo);
60 bool    bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
61 void    bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
62 size_t  bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo);
63 void    bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
64 #endif
65
66 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_))
67 JEMALLOC_INLINE bool
68 bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo)
69 {
70         unsigned rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
71         bitmap_t rg = bitmap[rgoff];
72         /* The bitmap is full iff the root group is 0. */
73         return (rg == 0);
74 }
75
76 JEMALLOC_INLINE bool
77 bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
78 {
79         size_t goff;
80         bitmap_t g;
81
82         assert(bit < binfo->nbits);
83         goff = bit >> LG_BITMAP_GROUP_NBITS;
84         g = bitmap[goff];
85         return (!(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))));
86 }
87
88 JEMALLOC_INLINE void
89 bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
90 {
91         size_t goff;
92         bitmap_t *gp;
93         bitmap_t g;
94
95         assert(bit < binfo->nbits);
96         assert(bitmap_get(bitmap, binfo, bit) == false);
97         goff = bit >> LG_BITMAP_GROUP_NBITS;
98         gp = &bitmap[goff];
99         g = *gp;
100         assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
101         g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
102         *gp = g;
103         assert(bitmap_get(bitmap, binfo, bit));
104         /* Propagate group state transitions up the tree. */
105         if (g == 0) {
106                 unsigned i;
107                 for (i = 1; i < binfo->nlevels; i++) {
108                         bit = goff;
109                         goff = bit >> LG_BITMAP_GROUP_NBITS;
110                         gp = &bitmap[binfo->levels[i].group_offset + goff];
111                         g = *gp;
112                         assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)));
113                         g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
114                         *gp = g;
115                         if (g != 0)
116                                 break;
117                 }
118         }
119 }
120
121 /* sfu: set first unset. */
122 JEMALLOC_INLINE size_t
123 bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo)
124 {
125         size_t bit;
126         bitmap_t g;
127         unsigned i;
128
129         assert(bitmap_full(bitmap, binfo) == false);
130
131         i = binfo->nlevels - 1;
132         g = bitmap[binfo->levels[i].group_offset];
133         bit = ffsl(g) - 1;
134         while (i > 0) {
135                 i--;
136                 g = bitmap[binfo->levels[i].group_offset + bit];
137                 bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffsl(g) - 1);
138         }
139
140         bitmap_set(bitmap, binfo, bit);
141         return (bit);
142 }
143
144 JEMALLOC_INLINE void
145 bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
146 {
147         size_t goff;
148         bitmap_t *gp;
149         bitmap_t g;
150         bool propagate;
151
152         assert(bit < binfo->nbits);
153         assert(bitmap_get(bitmap, binfo, bit));
154         goff = bit >> LG_BITMAP_GROUP_NBITS;
155         gp = &bitmap[goff];
156         g = *gp;
157         propagate = (g == 0);
158         assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
159         g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
160         *gp = g;
161         assert(bitmap_get(bitmap, binfo, bit) == false);
162         /* Propagate group state transitions up the tree. */
163         if (propagate) {
164                 unsigned i;
165                 for (i = 1; i < binfo->nlevels; i++) {
166                         bit = goff;
167                         goff = bit >> LG_BITMAP_GROUP_NBITS;
168                         gp = &bitmap[binfo->levels[i].group_offset + goff];
169                         g = *gp;
170                         propagate = (g == 0);
171                         assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)))
172                             == 0);
173                         g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK);
174                         *gp = g;
175                         if (propagate == false)
176                                 break;
177                 }
178         }
179 }
180
181 #endif
182
183 #endif /* JEMALLOC_H_INLINES */
184 /******************************************************************************/