38 memset(bmp->
bits, 0, size_bits * 8);
66 mask = (((uint64_t) 1) << bits) - 1;
68 if ( (mask & (*chunk)) == 0) {
78 uint64_t usable_bits = *chunk;
80 if (chunk + 1 == bmp->
end) {
83 usable_bits |= ((uint64_t) -1) << (shift);
86 if (!(usable_bits) ) {
90 *chunk = (((uint64_t) 1) << bits) - 1;
92 return ( ((
size_t) chunk) - ((
size_t) bmp->
bits) ) * 8;
98 int free_bits = 64 - __builtin_popcountl(usable_bits);
100 if (free_bits >= bits) {
102 uint64_t mask = (((uint64_t) 1) << bits) - 1;
104 for (shift = 0; shift <= 64 - bits; shift++) {
105 if ( (mask & (usable_bits) ) == 0)
117 return ( ((
size_t) chunk) - ((
size_t) bmp->
bits) ) * 8 + shift;
119 int free_end = (*chunk) ? __builtin_clzl(*chunk) : 64;
123 if (chunk + 1 == bmp->
end)
126 int remainder = bits - free_end;
129 *chunk |= ((uint64_t) -1) << (64 - free_end);
131 return ( ((
size_t) chunk) - ((
size_t) bmp->
bits) ) * 8 + (64 - free_end);
142 uint64_t first_mask = 0;
148 remainder = bits - 64;
151 free_end = __builtin_clzl(*chunk);
152 first_mask = (free_end) ? (((uint64_t) -1) << (64 - free_end)) : (0);
153 remainder = bits - free_end;
154 free_end = 64 - free_end;
160 if (chunk + 1 == bmp->
end)
163 if (remainder < 65) {
167 *chunk |= first_mask;
169 return ( ((
size_t) chunk) - ((
size_t) bmp->
bits) ) * 8 + free_end;
171 size_t span = remainder / 64;
172 size_t last_remainder = remainder & 63;
173 uint64_t last_mask = (((uint64_t) (!!last_remainder)) << (last_remainder)) - 1;
175 (void) last_remainder;
177 if (chunk + span + (!!last_remainder) >= bmp->
end)
180 uint64_t *citr = chunk + 1;
182 for (; c < span; c++) {
189 if (last_remainder) {
190 if ( (*citr) & last_mask)
196 memset(chunk + 1, 0xFF,
sizeof(uint64_t) * span);
198 *chunk |= first_mask;
202 return ( ((
size_t) chunk) - ((
size_t) bmp->
bits) ) * 8 + free_end;
231 for (chunk = bmp->
free_p; chunk < bmp->end; chunk++) {
237 for (chunk = bmp->
bits; chunk < bmp->free_p; chunk++) {
248 fprintf(stderr,
"%s(%lu) failed (free: %lu)!\n", __func__, bits,
utils_bitmap_free(bmp));
259 bmp->
bits[start / 64] &= ~(((uint64_t) 1) << (start & 63));
262 size_t end = start + bits;
263 size_t start_chunk = start / 64;
264 size_t end_chunk = (end - 1) / 64;
268 if (start_chunk == end_chunk) {
271 mask = ((((uint64_t) 1) << bits) - 1) << (start & 63);
275 bmp->
bits[start_chunk] &= ~mask;
279 size_t span = (end_chunk - start_chunk) - 1;
280 size_t start_mask = ((uint64_t) -1) << (start);
281 size_t end_mask = (end) ? (((uint64_t) -1) >> ((64 - end))) : (-1);
286 bmp->
bits[start_chunk] &= ~start_mask;
287 bmp->
bits[end_chunk] &= ~end_mask;
290 memset(bmp->
bits + start_chunk + 1, 0,
sizeof(uint64_t) * span);
301 size_t allocated = 0;
303 for (b = 0; b < (bmp->
size_bits + 63) / 64; b++)
305 allocated += __builtin_popcountl(bmp->
bits[b]);
316 for (b = 0; b < (bmp->
size_bits + 63) / 64; b++) {
317 uint64_t cchunk = bmp->
bits[b];
318 for (s = 0; s < 64; s++) {
319 fprintf(stderr,
"%d", (
int) (cchunk & 1));
322 fprintf(stderr,
" ");
324 fprintf(stderr,
"\n");
#define arax_assert(EXPR)
struct utils_bitmap utils_bitmap_s
size_t utils_bitmap_alloc_bits(utils_bitmap_s *bmp, size_t bits)
utils_bitmap_s * utils_bitmap_init(void *mem, size_t size_bits)
static size_t find_start_big(utils_bitmap_s *bmp, size_t bits, uint64_t *chunk)
void utils_bitmap_free_bits(utils_bitmap_s *bmp, size_t start, size_t bits)
size_t utils_bitmap_free(utils_bitmap_s *bmp)
size_t utils_bitmap_count_allocated(utils_bitmap_s *bmp)
size_t utils_bitmap_used(utils_bitmap_s *bmp)
size_t utils_bitmap_size(utils_bitmap_s *bmp)
static size_t find_start(utils_bitmap_s *bmp, size_t bits, uint64_t *chunk)
void utils_bitmap_print_bits(utils_bitmap_s *bmp)
static int find_end_small(size_t bits, uint64_t *chunk)
static size_t find_start_small(utils_bitmap_s *bmp, size_t bits, uint64_t *chunk)
#define utils_spinlock_lock(V)
#define utils_spinlock_init(V)
#define utils_spinlock_unlock(V)