1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#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 */
|