92 lines
2.0 KiB
C
92 lines
2.0 KiB
C
#include <libk/bm.h>
|
|
#include <libk/std.h>
|
|
#include <libk/string.h>
|
|
|
|
void bm_init (struct bm* bm, uint8_t* base, size_t nbits) {
|
|
bm->base = base;
|
|
bm->nbits = nbits;
|
|
memset (bm->base, 0, (nbits + 7) / 8);
|
|
}
|
|
|
|
/*
|
|
* Set a bit in a bitmap.
|
|
*/
|
|
void bm_set (struct bm* bm, size_t k) {
|
|
if (k >= bm->nbits)
|
|
return;
|
|
|
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
|
*b = ((*b) | (1 << (k % 8)));
|
|
}
|
|
|
|
/*
|
|
* Clear a bit in a bitmap.
|
|
*/
|
|
void bm_clear (struct bm* bm, size_t k) {
|
|
if (k >= bm->nbits)
|
|
return;
|
|
|
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
|
*b = ((*b) & ~(1 << (k % 8)));
|
|
}
|
|
|
|
/*
|
|
* Test (true/false) a bit in a bitmap.
|
|
*/
|
|
bool bm_test (struct bm* bm, size_t k) {
|
|
if (k >= bm->nbits)
|
|
return false;
|
|
|
|
uint8_t* b = (uint8_t*)((uintptr_t)bm->base + (k / 8));
|
|
return (*b) & (1 << (k % 8));
|
|
}
|
|
|
|
/*
|
|
* Set a range of bits in a bitmap. if starting bit is out of range, we fail.
|
|
*/
|
|
bool bm_set_region (struct bm* bm, size_t k, size_t m) {
|
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
|
return false;
|
|
|
|
for (size_t i = k; i < (k + m); i++) {
|
|
bool taken = bm_test (bm, i);
|
|
if (taken)
|
|
return false;
|
|
}
|
|
|
|
for (size_t i = k; i < (k + m); i++)
|
|
bm_set (bm, i);
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Clear a range of bits in a bitmap. starting bit must be in range.
|
|
*/
|
|
void bm_clear_region (struct bm* bm, size_t k, size_t m) {
|
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
|
return;
|
|
|
|
for (size_t i = k; i < (k + m); i++)
|
|
bm_clear (bm, i);
|
|
}
|
|
|
|
/*
|
|
* Test a range if bits in a bitmap. Return true if at least one bit
|
|
* is set, else return false (all bits clear). For convenience, if k or m
|
|
* are out of range, act as if the bits are set / bitmap is full - this is
|
|
* useful for implementing the physical memory manager algorithm.
|
|
*/
|
|
bool bm_test_region (struct bm* bm, size_t k, size_t m) {
|
|
if (((k + m) > bm->nbits) || (k + m) < k)
|
|
return true;
|
|
|
|
for (size_t i = k; i < (k + m); i++) {
|
|
bool test = bm_test (bm, i);
|
|
if (test)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|