summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2025-05-19 13:01:58 +0200
committerMichael Brown2025-05-19 20:35:56 +0200
commitc6ca3d3af83be57da8ba63df86185dc10fe7b715 (patch)
treeb4f6eeb3d7ee2d3d0dc0af1b3d9e15030421d65c /src/include
parent[memmap] Remove now-obsolete get_memmap() (diff)
downloadipxe-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.h16
-rw-r--r--src/include/ipxe/malloc.h91
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 {