Rizin
unix-like reverse engineering framework and cli tools
bitmap.h
Go to the documentation of this file.
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 #define BITMAP_MAXBITS (ZU(1) << LG_BITMAP_MAXBITS)
7 
8 typedef struct bitmap_level_s bitmap_level_t;
9 typedef struct bitmap_info_s bitmap_info_t;
10 typedef unsigned long bitmap_t;
11 #define LG_SIZEOF_BITMAP LG_SIZEOF_LONG
12 
13 /* Number of bits per group. */
14 #define LG_BITMAP_GROUP_NBITS (LG_SIZEOF_BITMAP + 3)
15 #define BITMAP_GROUP_NBITS (ZU(1) << LG_BITMAP_GROUP_NBITS)
16 #define BITMAP_GROUP_NBITS_MASK (BITMAP_GROUP_NBITS-1)
17 
18 /*
19  * Do some analysis on how big the bitmap is before we use a tree. For a brute
20  * force linear search, if we would have to call ffs_lu() more than 2^3 times,
21  * use a tree instead.
22  */
23 #if LG_BITMAP_MAXBITS - LG_BITMAP_GROUP_NBITS > 3
24 # define USE_TREE
25 #endif
26 
27 /* Number of groups required to store a given number of bits. */
28 #define BITMAP_BITS2GROUPS(nbits) \
29  ((nbits + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS)
30 
31 /*
32  * Number of groups required at a particular level for a given number of bits.
33  */
34 #define BITMAP_GROUPS_L0(nbits) \
35  BITMAP_BITS2GROUPS(nbits)
36 #define BITMAP_GROUPS_L1(nbits) \
37  BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits))
38 #define BITMAP_GROUPS_L2(nbits) \
39  BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits))))
40 #define BITMAP_GROUPS_L3(nbits) \
41  BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS( \
42  BITMAP_BITS2GROUPS((nbits)))))
43 
44 /*
45  * Assuming the number of levels, number of groups required for a given number
46  * of bits.
47  */
48 #define BITMAP_GROUPS_1_LEVEL(nbits) \
49  BITMAP_GROUPS_L0(nbits)
50 #define BITMAP_GROUPS_2_LEVEL(nbits) \
51  (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits))
52 #define BITMAP_GROUPS_3_LEVEL(nbits) \
53  (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits))
54 #define BITMAP_GROUPS_4_LEVEL(nbits) \
55  (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits))
56 
57 /*
58  * Maximum number of groups required to support LG_BITMAP_MAXBITS.
59  */
60 #ifdef USE_TREE
61 
62 #if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS
63 # define BITMAP_GROUPS_MAX BITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS)
64 #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2
65 # define BITMAP_GROUPS_MAX BITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS)
66 #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3
67 # define BITMAP_GROUPS_MAX BITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS)
68 #elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4
69 # define BITMAP_GROUPS_MAX BITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS)
70 #else
71 # error "Unsupported bitmap size"
72 #endif
73 
74 /* Maximum number of levels possible. */
75 #define BITMAP_MAX_LEVELS \
76  (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \
77  + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP)
78 
79 #else /* USE_TREE */
80 
81 #define BITMAP_GROUPS_MAX BITMAP_BITS2GROUPS(BITMAP_MAXBITS)
82 
83 #endif /* USE_TREE */
84 
85 #endif /* JEMALLOC_H_TYPES */
86 /******************************************************************************/
87 #ifdef JEMALLOC_H_STRUCTS
88 
89 struct bitmap_level_s {
90  /* Offset of this level's groups within the array of groups. */
91  size_t group_offset;
92 };
93 
94 struct bitmap_info_s {
95  /* Logical number of bits in bitmap (stored at bottom level). */
96  size_t nbits;
97 
98 #ifdef USE_TREE
99  /* Number of levels necessary for nbits. */
100  unsigned nlevels;
101 
102  /*
103  * Only the first (nlevels+1) elements are used, and levels are ordered
104  * bottom to top (e.g. the bottom level is stored in levels[0]).
105  */
106  bitmap_level_t levels[BITMAP_MAX_LEVELS+1];
107 #else /* USE_TREE */
108  /* Number of groups necessary for nbits. */
109  size_t ngroups;
110 #endif /* USE_TREE */
111 };
112 
113 #endif /* JEMALLOC_H_STRUCTS */
114 /******************************************************************************/
115 #ifdef JEMALLOC_H_EXTERNS
116 
117 void bitmap_info_init(bitmap_info_t *binfo, size_t nbits);
118 void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo);
119 size_t bitmap_size(const bitmap_info_t *binfo);
120 
121 #endif /* JEMALLOC_H_EXTERNS */
122 /******************************************************************************/
123 #ifdef JEMALLOC_H_INLINES
124 
125 #ifndef JEMALLOC_ENABLE_INLINE
126 bool bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo);
127 bool bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
128 void bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
129 size_t bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo);
130 void bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit);
131 #endif
132 
133 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_))
134 JEMALLOC_INLINE bool
135 bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo)
136 {
137 #ifdef USE_TREE
138  size_t rgoff = binfo->levels[binfo->nlevels].group_offset - 1;
139  bitmap_t rg = bitmap[rgoff];
140  /* The bitmap is full iff the root group is 0. */
141  return (rg == 0);
142 #else
143  size_t i;
144 
145  for (i = 0; i < binfo->ngroups; i++) {
146  if (bitmap[i] != 0)
147  return (false);
148  }
149  return (true);
150 #endif
151 }
152 
153 JEMALLOC_INLINE bool
154 bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
155 {
156  size_t goff;
157  bitmap_t g;
158  if (unlikely(bit > binfo->nbits))
159  return (false);
160 
161  goff = bit >> LG_BITMAP_GROUP_NBITS;
162  g = bitmap[goff];
163  return (!(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))));
164 }
165 
166 JEMALLOC_INLINE void
167 bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
168 {
169  size_t goff;
170  bitmap_t *gp;
171  bitmap_t g;
172 
173  assert(bit < binfo->nbits);
174  assert(!bitmap_get(bitmap, binfo, bit));
175  goff = bit >> LG_BITMAP_GROUP_NBITS;
176  gp = &bitmap[goff];
177  g = *gp;
178  assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
179  g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
180  *gp = g;
181  assert(bitmap_get(bitmap, binfo, bit));
182 #ifdef USE_TREE
183  /* Propagate group state transitions up the tree. */
184  if (g == 0) {
185  unsigned i;
186  for (i = 1; i < binfo->nlevels; i++) {
187  bit = goff;
188  goff = bit >> LG_BITMAP_GROUP_NBITS;
189  gp = &bitmap[binfo->levels[i].group_offset + goff];
190  g = *gp;
191  assert(g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)));
192  g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
193  *gp = g;
194  if (g != 0)
195  break;
196  }
197  }
198 #endif
199 }
200 
201 /* sfu: set first unset. */
202 JEMALLOC_INLINE size_t
203 bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo)
204 {
205  size_t bit;
206  bitmap_t g;
207  unsigned i;
208 
209  assert(!bitmap_full(bitmap, binfo));
210 
211 #ifdef USE_TREE
212  i = binfo->nlevels - 1;
213  g = bitmap[binfo->levels[i].group_offset];
214  bit = ffs_lu(g) - 1;
215  while (i > 0) {
216  i--;
217  g = bitmap[binfo->levels[i].group_offset + bit];
218  bit = (bit << LG_BITMAP_GROUP_NBITS) + (ffs_lu(g) - 1);
219  }
220 #else
221  i = 0;
222  g = bitmap[0];
223  while ((bit = ffs_lu(g)) == 0) {
224  i++;
225  g = bitmap[i];
226  }
227  bit = (i << LG_BITMAP_GROUP_NBITS) + (bit - 1);
228 #endif
229  bitmap_set(bitmap, binfo, bit);
230  return (bit);
231 }
232 
233 JEMALLOC_INLINE void
234 bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit)
235 {
236  size_t goff;
237  bitmap_t *gp;
238  bitmap_t g;
239  RZ_UNUSED bool propagate;
240 
241  assert(bit < binfo->nbits);
242  assert(bitmap_get(bitmap, binfo, bit));
243  goff = bit >> LG_BITMAP_GROUP_NBITS;
244  gp = &bitmap[goff];
245  g = *gp;
246  propagate = (g == 0);
247  assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK))) == 0);
248  g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
249  *gp = g;
250  assert(!bitmap_get(bitmap, binfo, bit));
251 #ifdef USE_TREE
252  /* Propagate group state transitions up the tree. */
253  if (propagate) {
254  unsigned i;
255  for (i = 1; i < binfo->nlevels; i++) {
256  bit = goff;
257  goff = bit >> LG_BITMAP_GROUP_NBITS;
258  gp = &bitmap[binfo->levels[i].group_offset + goff];
259  g = *gp;
260  propagate = (g == 0);
261  assert((g & (ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK)))
262  == 0);
263  g ^= ZU(1) << (bit & BITMAP_GROUP_NBITS_MASK);
264  *gp = g;
265  if (!propagate)
266  break;
267  }
268  }
269 #endif /* USE_TREE */
270 }
271 
272 #endif
273 
274 #endif /* JEMALLOC_H_INLINES */
275 /******************************************************************************/
lzma_index ** i
Definition: index.h:629
RzCryptoSelector bit
Definition: crypto.c:16
struct @667 g
#define JEMALLOC_INLINE
#define ZU(z)
#define unlikely(expr)
Definition: lz4.c:177
assert(limit<=UINT32_MAX/2)
#define bitmap_init
#define bitmap_unset
#define ffs_lu
#define bitmap_set
#define bitmap_full
#define bitmap_info_init
#define bitmap_get
#define bitmap_sfu
#define bitmap_size
#define RZ_UNUSED
Definition: rz_types.h:73