#include <sys/bitmap.h>
#include <sys/types.h>
#include <stdlib.h>
struct bitmap *
bitmap_create(void *mem, uint32_t available, size_t bitmap_size) {
/* check, if it fits */
if (available < bitmap_required_size(bitmap_size)) {
return NULL;
}
struct bitmap *bm = (struct bitmap *)mem;
bm->size = bitmap_size;
bm->first_clear = 0;
bm->area = (uint32_t *)(mem + sizeof(struct bitmap *));
memset(bm->area, 0, ((bitmap_size + 31) / 32) * 4);
return NULL;
}
void
bitmap_set(struct bitmap *bm, uint32_t index) {
uint32_t area_index = index / 32;
uint32_t mask = 1 << (index % 32);
bm->area[area_index] |= mask;
}
void
bitmap_clear(struct bitmap *bm, uint32_t index) {
uint32_t area_index = index / 32;
uint32_t mask = ~(1 << (index % 32));
bm->area[area_index] &= mask;
if (area_index < bm->first_clear) {
bm->first_clear = area_index;
}
}
int
bitmap_get(struct bitmap *bm, uint32_t index) {
uint32_t area_index = index / 32;
uint32_t mask = 1 << (index % 32);
return (bm->area[area_index] & mask);
}
uint32_t
bitmap_find_clear(struct bitmap *bm) {
for(uint32_t area_index = bm->first_clear; area_index < bm->size; ++area_index) {
if (bm->area[area_index] != 0xffffffff) {
area_index *= 32;
uint32_t value = bm->area[area_index];
while (value & 1) {
area_index++;
value >>= 1;
}
return area_index;
}
}
return 0;
}
void
bitmap_range_update(struct bitmap *bm, uint32_t start, uint32_t count, int value) {
// TODO: this is a very naive implementation, replace with a real one
if (value) {
for (uint32_t index=start; index<start+count; ++index) {
bitmap_set(bm, index);
}
} else {
for (uint32_t index=start; index<start+count; ++index) {
bitmap_clear(bm, index);
}
}
}