bitmap_alloc now calls mmap on all new allocations

This commit is contained in:
2023-03-04 03:47:52 -06:00
parent 420ed7ba65
commit 851b31ad2d
2 changed files with 51 additions and 8 deletions

View File

@@ -96,6 +96,12 @@ typedef struct bitmap_heap_descriptor_t
*/ */
unsigned long offset; unsigned long offset;
/**
* @brief Function pointer which, if not null, will be called whenever
* a region on the heap is allocated for the first time.
*/
int (*mmap)(void *location, unsigned long size)
} bitmap_heap_descriptor_t; } bitmap_heap_descriptor_t;
/** /**
@@ -197,11 +203,9 @@ unsigned long bitmap_size(const memory_map_t *map, unsigned long block_size, uns
* *
* @param heap A pointer to the structure describing the heap * @param heap A pointer to the structure describing the heap
* @param map A pointer to the structure providing an initial memory layout * @param map A pointer to the structure providing an initial memory layout
* @param mmap A callback function used to map memory in the virtual address
* space * space
* @return int 0 upon success, nonzero upon failure. * @return int 0 upon success, nonzero upon failure.
*/ */
int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map, int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map);
int (*mmap)(void *location, unsigned long size));
#endif #endif

View File

@@ -4,6 +4,7 @@
static const int BIT_AVAIL = 0; static const int BIT_AVAIL = 0;
static const int BIT_USED = 1; static const int BIT_USED = 1;
static const int BIT_MAPPED = 2;
/* /*
* Sets all elements in the cache's underlying array to 0. * Sets all elements in the cache's underlying array to 0.
@@ -198,6 +199,17 @@ static inline int block_index(bitmap_heap_descriptor_t *heap,
return (location / (heap->block_size * ((unsigned long)1 << height))) + (1 << (heap->height - height)); return (location / (heap->block_size * ((unsigned long)1 << height))) + (1 << (heap->height - height));
} }
/*
* Computes the location of the block at `index` and `height`
*/
static inline unsigned long block_location(bitmap_heap_descriptor_t *heap,
int index, int height)
{
return heap->offset
+ (heap->block_size << height)
* (index - ((unsigned long)1 << (heap->height - height)));
}
/* /*
* Marks the indicated block as unavailable, and marks its children as both * 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 * available. Stores the right-hand child in the cache, and returns the index
@@ -283,6 +295,25 @@ static int find_free_region(bitmap_heap_descriptor_t *heap, int height)
return split_block(heap, find_free_region(heap, height + 1)); return split_block(heap, find_free_region(heap, height + 1));
} }
static int map_region(bitmap_heap_descriptor_t *heap, int index, int height)
{
int status = 0;
if(!test_bit(heap, index, BIT_MAPPED) && height > 0)
{
status = map_region(heap, index * 2, height - 1);
if(!status)
{
status = map_region(heap, (index * 2) + 1, height - 1);
}
set_bit(heap, index, BIT_MAPPED);
}
else if(!test_bit(heap, index, BIT_MAPPED) && height == 0)
{
status = heap->mmap((void*)block_location(heap, index, 0), heap->block_size);
}
return status;
}
static unsigned long compute_memory_size(const memory_map_t *map) static unsigned long compute_memory_size(const memory_map_t *map)
{ {
// Find the last available region in the memory map. // Find the last available region in the memory map.
@@ -350,7 +381,7 @@ static void initialize_bitmap(bitmap_heap_descriptor_t *heap, const memory_map_t
continue; continue;
} }
unsigned long location = (map->array[i].location + heap->block_size - 1);// & ~(heap->block_size - 1); unsigned long location = (map->array[i].location + heap->block_size - 1);
location -= location % heap->block_size; location -= location % heap->block_size;
unsigned long region_end = map->array[i].location + map->array[i].size; unsigned long region_end = map->array[i].location + map->array[i].size;
@@ -455,7 +486,14 @@ unsigned long reserve_region(bitmap_heap_descriptor_t *heap, unsigned long size)
clear_bit(heap, index, BIT_AVAIL); clear_bit(heap, index, BIT_AVAIL);
set_bit(heap, index, BIT_USED); set_bit(heap, index, BIT_USED);
heap->free_block_count -= 1 << height; heap->free_block_count -= 1 << height;
return heap->offset + (heap->block_size << height) * (index - ((unsigned long)1 << (heap->height - height))); if(heap->mmap && map_region(heap, index, height))
{
return NOMEM;
}
else
{
return block_location(heap, index, height);
}
} }
else else
{ {
@@ -485,7 +523,7 @@ unsigned long bitmap_size(const memory_map_t *map, unsigned long block_size, uns
return 1UL << llog2((block_bits * compute_memory_size(map) / block_size) / 4); return 1UL << llog2((block_bits * compute_memory_size(map) / block_size) / 4);
} }
int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map, int (*mmap)(void *location, unsigned long size)) int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map)
{ {
if(construct_heap_desc(heap, map)) if(construct_heap_desc(heap, map))
{ {
@@ -495,7 +533,8 @@ int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map, int (*mma
if(heap->bitmap == (unsigned long*)0) if(heap->bitmap == (unsigned long*)0)
{ {
int map_index = 0; int map_index = 0;
while(map->array[map_index].size < heap->bitmap_size) while(map->array[map_index].type != M_AVAILABLE
|| map->array[map_index].size < heap->bitmap_size)
{ {
map_index++; map_index++;
if(map_index >= map->size) if(map_index >= map->size)
@@ -506,7 +545,7 @@ int initialize_heap(bitmap_heap_descriptor_t *heap, memory_map_t *map, int (*mma
heap->bitmap = (unsigned long*)(heap->offset + map->array[map_index].location); heap->bitmap = (unsigned long*)(heap->offset + map->array[map_index].location);
memmap_insert_region(map, map->array[map_index].location, heap->bitmap_size, M_UNAVAILABLE); memmap_insert_region(map, map->array[map_index].location, heap->bitmap_size, M_UNAVAILABLE);
if(mmap && mmap(heap->bitmap, heap->bitmap_size)) if(heap->mmap && heap->mmap(heap->bitmap, heap->bitmap_size))
{ {
return -1; return -1;
} }