| #ifndef _IPXE_MALLOC_H |
| #define _IPXE_MALLOC_H |
| |
| #include <stdint.h> |
| |
| /** @file |
| * |
| * Dynamic memory allocation |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| FILE_SECBOOT ( PERMITTED ); |
| |
| /* |
| * Prototypes for the standard functions (malloc() et al) are in |
| * stdlib.h. Include <ipxe/malloc.h> only if you need the |
| * non-standard functions, such as malloc_phys(). |
| * |
| */ |
| #include <stdlib.h> |
| #include <ipxe/list.h> |
| #include <ipxe/tables.h> |
| #include <valgrind/memcheck.h> |
| |
| /** |
| * Address for zero-length memory blocks |
| * |
| * @c malloc(0) or @c realloc(ptr,0) will return the special value @c |
| * NOWHERE. Calling @c free(NOWHERE) will have no effect. |
| * |
| * 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. |
| * |
| * 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. |
| */ |
| #define NOWHERE ( ( void * ) ~( ( intptr_t ) 0 ) ) |
| |
| /** 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 { |
| /** |
| * Discard some cached data |
| * |
| * @ret discarded Number of cached items discarded |
| */ |
| unsigned int ( * discard ) ( void ); |
| }; |
| |
| /** Cache discarder table */ |
| #define CACHE_DISCARDERS __table ( struct cache_discarder, "cache_discarders" ) |
| |
| /** Declare a cache discarder */ |
| #define __cache_discarder( cost ) __table_entry ( CACHE_DISCARDERS, cost ) |
| |
| /** @defgroup cache_cost Cache discarder costs |
| * |
| * @{ |
| */ |
| |
| #define CACHE_CHEAP 01 /**< Items with a low replacement cost */ |
| #define CACHE_NORMAL 02 /**< Items with a normal replacement cost */ |
| #define CACHE_EXPENSIVE 03 /**< Items with a high replacement cost */ |
| |
| /** @} */ |
| |
| #endif /* _IPXE_MALLOC_H */ |