diff options
| author | Michael Brown | 2025-05-19 13:01:58 +0200 |
|---|---|---|
| committer | Michael Brown | 2025-05-19 20:35:56 +0200 |
| commit | c6ca3d3af83be57da8ba63df86185dc10fe7b715 (patch) | |
| tree | b4f6eeb3d7ee2d3d0dc0af1b3d9e15030421d65c /src/include | |
| parent | [memmap] Remove now-obsolete get_memmap() (diff) | |
| download | ipxe-c6ca3d3af83be57da8ba63df86185dc10fe7b715.tar.gz ipxe-c6ca3d3af83be57da8ba63df86185dc10fe7b715.tar.xz ipxe-c6ca3d3af83be57da8ba63df86185dc10fe7b715.zip | |
[malloc] Allow for the existence of multiple heaps
Create a generic model of a heap as a list of free blocks with
optional methods for growing and shrinking the heap.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/ipxe/linux/linux_uaccess.h | 16 | ||||
| -rw-r--r-- | src/include/ipxe/malloc.h | 91 |
2 files changed, 47 insertions, 60 deletions
diff --git a/src/include/ipxe/linux/linux_uaccess.h b/src/include/ipxe/linux/linux_uaccess.h index a5d7d73f3..7770ea90e 100644 --- a/src/include/ipxe/linux/linux_uaccess.h +++ b/src/include/ipxe/linux/linux_uaccess.h @@ -7,9 +7,9 @@ * * We have no concept of the underlying physical addresses, since * these are not exposed to userspace. We provide a stub - * implementation of virt_to_phys() since this is required by - * alloc_memblock(). We provide a matching stub implementation of - * phys_to_virt(). + * implementation of virt_to_phys() since this is required by the heap + * allocator to determine physical address alignment. We provide a + * matching stub implementation of phys_to_virt(). */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); @@ -31,11 +31,11 @@ UACCESS_INLINE ( linux, virt_to_phys ) ( volatile const void *virt ) { /* We do not know the real underlying physical address. We * provide this stub implementation only because it is - * required by alloc_memblock() (which allocates memory with - * specified physical address alignment). We assume that the - * low-order bits of virtual addresses match the low-order - * bits of physical addresses, and so simply returning the - * virtual address will suffice for the purpose of determining + * required in order to allocate memory with a specified + * physical address alignment. We assume that the low-order + * bits of virtual addresses match the low-order bits of + * physical addresses, and so simply returning the virtual + * address will suffice for the purpose of determining * alignment. */ return ( ( physaddr_t ) virt ); diff --git a/src/include/ipxe/malloc.h b/src/include/ipxe/malloc.h index 8c3a7769d..6f30916d7 100644 --- a/src/include/ipxe/malloc.h +++ b/src/include/ipxe/malloc.h @@ -18,6 +18,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ #include <stdlib.h> +#include <ipxe/list.h> #include <ipxe/tables.h> #include <valgrind/memcheck.h> @@ -39,62 +40,48 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ #define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) -extern size_t freemem; -extern size_t usedmem; -extern size_t maxusedmem; +/** A heap */ +struct heap { + /** List of free memory blocks */ + struct list_head blocks; -extern void * __malloc alloc_memblock ( size_t size, size_t align, - size_t offset ); -extern void free_memblock ( void *ptr, size_t size ); -extern void mdumpfree ( void ); + /** Total amount of free memory */ + size_t freemem; + /** Total amount of used memory */ + size_t usedmem; + /** Maximum amount of used memory */ + size_t maxusedmem; -/** - * Allocate memory with specified physical alignment and offset - * - * @v size Requested size - * @v align Physical alignment - * @v offset Offset from physical alignment - * @ret ptr Memory, or NULL - * - * @c align must be a power of two. @c size may not be zero. - */ -static inline void * __malloc malloc_phys_offset ( size_t size, - size_t phys_align, - size_t offset ) { - void * ptr = alloc_memblock ( size, phys_align, offset ); - if ( ptr && size ) - VALGRIND_MALLOCLIKE_BLOCK ( ptr, size, 0, 0 ); - return ptr; -} + /** + * Attempt to grow heap (optional) + * + * @v size Failed allocation size + * @ret grown Heap has grown: retry allocations + */ + unsigned int ( * grow ) ( size_t size ); + /** + * Allow heap to shrink (optional) + * + * @v ptr Start of free block + * @v size Size of free block + * @ret shrunk Heap has shrunk: discard block + * + * Note that the discarded block will be accessed once after + * this method returns, in order to clear the free block + * metadata. + */ + unsigned int ( * shrink ) ( void *ptr, size_t size ); +}; -/** - * Allocate memory with specified physical alignment - * - * @v size Requested size - * @v align Physical alignment - * @ret ptr Memory, or NULL - * - * @c align must be a power of two. @c size may not be zero. - */ -static inline void * __malloc malloc_phys ( size_t size, size_t phys_align ) { - return malloc_phys_offset ( size, phys_align, 0 ); -} +extern void * heap_realloc ( struct heap *heap, void *old_ptr, + size_t new_size ); +extern void heap_dump ( struct heap *heap ); +extern void heap_populate ( struct heap *heap, void *start, size_t len ); -/** - * Free memory allocated with malloc_phys() - * - * @v ptr Memory allocated by malloc_phys(), or NULL - * @v size Size of memory, as passed to malloc_phys() - * - * Memory allocated with malloc_phys() can only be freed with - * free_phys(); it cannot be freed with the standard free(). - * - * If @c ptr is NULL, no action is taken. - */ -static inline void free_phys ( void *ptr, size_t size ) { - VALGRIND_FREELIKE_BLOCK ( ptr, 0 ); - free_memblock ( ptr, size ); -} +extern void * __malloc malloc_phys_offset ( size_t size, size_t phys_align, + size_t offset ); +extern void * __malloc malloc_phys ( size_t size, size_t phys_align ); +extern void free_phys ( void *ptr, size_t size ); /** A cache discarder */ struct cache_discarder { |
