Added functions to read/write bits in bitmap metadata

This commit is contained in:
2023-03-03 03:44:44 -06:00
parent eb15a7764e
commit 6576876109
2 changed files with 81 additions and 1 deletions

View File

@@ -98,6 +98,33 @@ typedef struct bitmap_heap_descriptor_t
} bitmap_heap_descriptor_t;
/**
* @brief Reads the given bit from the metadata of the memory block at
* `location`.
*
* `location` must have be a location previously returned by `reserve_region`,
* and not have been subsequently freed. `bit` must be less than the
* `block_bits` field in `heap`.
*
* @returns nonzero if `bit` is set, 0 otherwise. If `bit` is not less than the
* `block_bits` field in `heap`, returns nonzero.
*/
unsigned long read_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
unsigned long bit);
/**
* @brief Writes to the given bit in the metadata of the memory block at
* `location`.
*
* `location` must have be a location previously returned by `reserve_region`,
* and not have been subsequently freed. `bit` must be less than the
* `block_bits` field in `heap`.
*
* @returns `value` if bit was written to, nonzero otherwise
*/
int write_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
unsigned long bit, int value);
/**
* @brief Reserves a region of memory within the heap containing at least `size`
* bytes.

View File

@@ -197,6 +197,15 @@ static inline void uncache(bitmap_heap_descriptor_t *heap, int index)
}
}
/*
* Computes the bitmap index of the block at `location` and `height`.
*/
static inline int block_index(bitmap_heap_descriptor_t *heap,
unsigned long location, unsigned long height)
{
return (location / (heap->block_size * ((unsigned long)1 << height))) + (1 << (heap->height - height));
}
/*
* Marks the indicated block as unavailable, and marks its children as both
* available. Stores the right-hand child in the cache, and returns the index
@@ -401,6 +410,50 @@ static void initialize_bitmap(bitmap_heap_descriptor_t *heap, const memory_map_t
}
}
unsigned long read_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
unsigned long bit)
{
int index = block_index(heap, location, 0);
while(index && !test_bit(heap, index, BIT_USED))
{
index /= 2;
}
if(index)
{
return test_bit(heap, index, bit);
}
else
{
return 1;
}
}
int write_bit(bitmap_heap_descriptor_t *heap, unsigned long location,
unsigned long bit, int value)
{
int index = block_index(heap, location, 0);
while(index && !test_bit(heap, index, BIT_USED))
{
index /= 2;
}
if(index && value)
{
set_bit(heap, index, bit);
return value;
}
else if(index)
{
clear_bit(heap, index, bit);
return value;
}
else
{
return 1;
}
}
unsigned long reserve_region(bitmap_heap_descriptor_t *heap, unsigned long size)
{
int height = llog2((size - 1) / heap->block_size + 1);
@@ -422,7 +475,7 @@ void free_region(bitmap_heap_descriptor_t *heap, unsigned long location, unsigne
{
location -= heap->offset;
int height = llog2(size / heap->block_size);
int index = (location / (heap->block_size * ((unsigned long)1 << height))) + (1 << (heap->height - height));
int index = block_index(heap, location, height);
while(!test_bit(heap, index, BIT_USED))
{
height++;