diff options
| author | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
| commit | 8e82785c584dc13e20f9229decb95bd17bbe9cd1 (patch) | |
| tree | a8b359e59196be5b2e3862bed189107f4bc9975f /src/include/ipxe/malloc.h | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [prefix] Make unlzma.S compatible with 386 class CPUs (diff) | |
| download | ipxe-openslx.tar.gz ipxe-openslx.tar.xz ipxe-openslx.zip | |
Merge branch 'master' into openslxopenslx
Diffstat (limited to 'src/include/ipxe/malloc.h')
| -rw-r--r-- | src/include/ipxe/malloc.h | 112 |
1 files changed, 61 insertions, 51 deletions
diff --git a/src/include/ipxe/malloc.h b/src/include/ipxe/malloc.h index 180ca001d..fac46bd00 100644 --- a/src/include/ipxe/malloc.h +++ b/src/include/ipxe/malloc.h @@ -10,6 +10,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /* * Prototypes for the standard functions (malloc() et al) are in @@ -18,66 +19,75 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ #include <stdlib.h> +#include <ipxe/list.h> #include <ipxe/tables.h> #include <valgrind/memcheck.h> -extern size_t freemem; -extern size_t usedmem; -extern size_t maxusedmem; - -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 mpopulate ( void *start, size_t len ); -extern void mdumpfree ( void ); - /** - * 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 + * Address for zero-length memory blocks * - * @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; -} - -/** - * Allocate memory with specified physical alignment + * @c malloc(0) or @c realloc(ptr,0) will return the special value @c + * NOWHERE. Calling @c free(NOWHERE) will have no effect. * - * @v size Requested size - * @v align Physical alignment - * @ret ptr Memory, or NULL + * This is consistent with the ANSI C standards, which state that + * "either NULL or a pointer suitable to be passed to free()" must be + * returned in these cases. Using a special non-NULL value means that + * the caller can take a NULL return value to indicate failure, + * without first having to check for a requested size of zero. * - * @c align must be a power of two. @c size may not be zero. + * Code outside of the memory allocators themselves does not ever need + * to refer to the actual value of @c NOWHERE; this is an internal + * definition. */ -static inline void * __malloc malloc_phys ( size_t size, size_t phys_align ) { - return malloc_phys_offset ( size, phys_align, 0 ); -} +#define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) -/** - * 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 ); -} +/** A heap */ +struct heap { + /** List of free memory blocks */ + struct list_head blocks; + + /** Alignment for free memory blocks */ + size_t align; + /** Alignment for size-tracked allocations */ + size_t ptr_align; + + /** Total amount of free memory */ + size_t freemem; + /** Total amount of used memory */ + size_t usedmem; + /** Maximum amount of used memory */ + size_t maxusedmem; + + /** + * 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 ); +}; + +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 ); + +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 { |
