diff --git a/kernel-src/include/bitmap.h b/kernel-src/include/bitmap.h index 8f93e6f9..e431325c 100644 --- a/kernel-src/include/bitmap.h +++ b/kernel-src/include/bitmap.h @@ -1,6 +1,7 @@ #ifndef _BITMAP_H #define _BITMAP_H +#include #include typedef struct { @@ -9,8 +10,10 @@ typedef struct { } bitmap_t; int bitmap_init(bitmap_t *bitmap, size_t size); +void bitmap_destroy(bitmap_t *bitmap); void bitmap_set(bitmap_t *bitmap, long idx, int v); +void bitmap_set_range(bitmap_t *bitmap, long start, long count, int v); +bool bitmap_get(bitmap_t *bitmap, long idx); long bitmap_find_first_set(bitmap_t *bitmap); - #endif diff --git a/kernel-src/lib/bitmap.c b/kernel-src/lib/bitmap.c index 1de9b365..8b296466 100644 --- a/kernel-src/lib/bitmap.c +++ b/kernel-src/lib/bitmap.c @@ -4,22 +4,58 @@ #include #include +#define BYTE_INDEX(idx) ((idx) / (sizeof(long) * 8)) +#define BIT_INDEX(idx) ((idx) % (sizeof(long) * 8)) + int bitmap_init(bitmap_t *bitmap, size_t size) { bitmap->data = alloc(size); bitmap->size = size; + if (bitmap->data != NULL) + memset(bitmap->data, 0, size); + return bitmap->data ? 0 : ENOMEM; } -void bitmap_set(bitmap_t *bitmap, long idx, int v) { - __assert(bitmap->size > idx); +void bitmap_destroy(bitmap_t *bitmap) { + free(bitmap->data); + bitmap->data = NULL; + bitmap->size = 0; +} - long bit = 1llu << (idx % sizeof(*bitmap->data)); +void bitmap_set(bitmap_t *bitmap, long idx, int v) { + __assert(idx < bitmap->size); + + long *ptr = &bitmap->data[BYTE_INDEX(idx)]; + long bit = 1lu << BIT_INDEX(idx); if (v) - bitmap->data[idx / sizeof(*bitmap->data)] |= bit; + *ptr |= bit; else - bitmap->data[idx / sizeof(*bitmap->data)] &= ~bit; + *ptr &= ~bit; +} + +void bitmap_set_range(bitmap_t *bitmap, long start, long count, int v) { + __assert(start + count <= bitmap->size); + + for (long i = 0; i < count; ++i) { + long idx = start + i; + + long *ptr = &bitmap->data[BYTE_INDEX(idx)]; + long bit = 1lu << BIT_INDEX(idx); + + if (v) + *ptr |= bit; + else + *ptr &= ~bit; + } +} + +bool bitmap_get(bitmap_t *bitmap, long idx) { + __assert(idx < bitmap->size); + + long bit = 1lu << BIT_INDEX(idx); + return bitmap->data[BYTE_INDEX(idx)] & bit; } long bitmap_find_first_set(bitmap_t *bitmap) {