|
PatchworkOS
2ca1c69
A non-POSIX operating system.
|
Internal Heap Implementation. More...
Internal Heap Implementation.
We use a "segregated free list" allocator with a set of bins where each bin stores free blocks of size \(n \cdot 64\) bytes where \(n\) is the index of the bin, up to _HEAP_LARGE_ALLOC_THRESHOLD. Above this size, blocks are mapped directly.
To allow for coalescing of free blocks, all blocks (allocated and free) are additionally stored in a linked list sorted by address. When a block is freed, we check the previous and next blocks in memory to see if they are free, and if so we merge them into a single larger block.
Included is the internal heap allocation, the functions that the kernel and user space should use are the expected malloc(), free(), realloc(), etc functions.
Data Structures | |
| struct | _heap_header_t |
| struct | _heap_header |
| Header for each heap block. More... | |
Macros | |
| #define | _HEAP_ALIGNMENT 64 |
| #define | _HEAP_HEADER_MAGIC 0xDEADBEEF |
| #define | _HEAP_LARGE_ALLOC_THRESHOLD (PAGE_SIZE * 4) |
| #define | _HEAP_NUM_BINS (_HEAP_LARGE_ALLOC_THRESHOLD / _HEAP_ALIGNMENT) |
Enumerations | |
| enum | _heap_flags_t { _HEAP_ALLOCATED = 1 << 0 , _HEAP_MAPPED = 1 << 1 , _HEAP_ZEROED = 1 << 2 } |
| Flags for heap blocks. More... | |
Functions | |
| void | _heap_init (void) |
| Initialize the heap. | |
| void | _heap_acquire (void) |
| Acquire the heap lock. | |
| void | _heap_release (void) |
| Release the heap lock. | |
| uint64_t | _heap_get_bin_index (uint64_t size) |
| Get the bin index for a given size. | |
| _heap_header_t * | _heap_block_new (uint64_t minSize) |
Directly maps a new heap block of at least minSize bytes. | |
| void | _heap_block_split (_heap_header_t *block, uint64_t size) |
Splits a heap block into two blocks, the first of size bytes and the second with the remaining bytes. | |
| void | _heap_add_to_free_list (_heap_header_t *block) |
| Adds a block to the appropriate free list. | |
| void | _heap_remove_from_free_list (_heap_header_t *block) |
| Removes a block from its free list. | |
| _heap_header_t * | _heap_alloc (uint64_t size) |
| Allocates a block of memory of given size. | |
| void | _heap_free (_heap_header_t *block) |
| Frees a previously allocated heap block. | |
| void * | _heap_map_memory (uint64_t size) |
| Directly maps memory of the given size. | |
| void | _heap_unmap_memory (void *addr, uint64_t size) |
| Unmaps previously mapped memory. | |
Variables | |
| list_t | _heapList |
| A list of all blocks sorted by address. | |
| #define _HEAP_ALIGNMENT 64 |
| #define _HEAP_HEADER_MAGIC 0xDEADBEEF |
| #define _HEAP_LARGE_ALLOC_THRESHOLD (PAGE_SIZE * 4) |
| #define _HEAP_NUM_BINS (_HEAP_LARGE_ALLOC_THRESHOLD / _HEAP_ALIGNMENT) |
| enum _heap_flags_t |
| void _heap_init | ( | void | ) |
| void _heap_acquire | ( | void | ) |
Acquire the heap lock.
Must be paired with a call to _heap_release().
Definition at line 84 of file heap.c.
| void _heap_release | ( | void | ) |
| _heap_header_t * _heap_block_new | ( | uint64_t | minSize | ) |
Directly maps a new heap block of at least minSize bytes.
Must be called with the heap acquired.
| minSize | The minimum size of the block to create, in bytes. |
NULL. Definition at line 127 of file heap.c.
| void _heap_block_split | ( | _heap_header_t * | block, |
| uint64_t | size | ||
| ) |
Splits a heap block into two blocks, the first of size bytes and the second with the remaining bytes.
Must be called with the heap acquired.
| block | The block to split. |
| size | The size of the first block after the split, in bytes. |
Definition at line 172 of file heap.c.
| void _heap_add_to_free_list | ( | _heap_header_t * | block | ) |
Adds a block to the appropriate free list.
Must be called with the heap acquired.
Will not actually free the block, just add it to the free list.
Used to keep track of which bins have free blocks using a bitmap.
| block | The block to add. |
Definition at line 202 of file heap.c.
| void _heap_remove_from_free_list | ( | _heap_header_t * | block | ) |
Removes a block from its free list.
Must be called with the heap acquired.
Will not actually allocate the block, just remove it from the free list.
Used to keep track of which bins have free blocks using a bitmap.
| block | The block to remove. |
Definition at line 223 of file heap.c.
| _heap_header_t * _heap_alloc | ( | uint64_t | size | ) |
Allocates a block of memory of given size.
Must be called with the heap acquired.
| size | The size of memory to allocate, in bytes. |
NULL and errno is set. Definition at line 247 of file heap.c.
| void _heap_free | ( | _heap_header_t * | block | ) |
| void * _heap_map_memory | ( | uint64_t | size | ) |
Directly maps memory of the given size.
In the kernel this function uses the VMM to map new memory, in user space it uses /dev/zero.
| size | The size of memory to map, in bytes. |
NULL. Definition at line 39 of file heap.c.
| void _heap_unmap_memory | ( | void * | addr, |
| uint64_t | size | ||
| ) |
Unmaps previously mapped memory.
In the kernel this function uses the VMM to unmap memory, in user space it uses the munmap() function.
| addr | The address of the memory to unmap. |
| size | The size of memory to unmap, in bytes. |
Definition at line 50 of file heap.c.