Added functions to read/write bits in bitmap metadata
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user