iPXE
malloc.c File Reference

Dynamic memory allocation. More...

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <ipxe/io.h>
#include <ipxe/list.h>
#include <ipxe/init.h>
#include <ipxe/refcnt.h>
#include <ipxe/malloc.h>
#include <valgrind/memcheck.h>

Go to the source code of this file.

Data Structures

struct  memory_block
 A free block of memory. More...
struct  autosized_block
 A block of allocated memory complete with size information. More...

Macros

#define MIN_MEMBLOCK_ALIGN   ( 4 * sizeof ( void * ) )
 Physical address alignment maintained for free blocks of memory.
#define HEAP_SIZE   ( 4096 * 1024 )
 Heap area size.
#define HEAP_ALIGN   MIN_MEMBLOCK_ALIGN
 Heap area alignment.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void valgrind_make_blocks_defined (struct heap *heap)
 Mark all blocks in free list as defined.
static void valgrind_make_blocks_noaccess (struct heap *heap)
 Mark all blocks in free list as inaccessible.
static void check_blocks (struct heap *heap)
 Check integrity of the blocks in the free list.
static unsigned int discard_cache (size_t size __unused)
 Discard some cached data.
static void discard_all_cache (void)
 Discard all cached data.
static void * heap_alloc_block (struct heap *heap, size_t size, size_t align, size_t offset)
 Allocate a memory block.
static void heap_free_block (struct heap *heap, void *ptr, size_t size)
 Free a memory block.
void * heap_realloc (struct heap *heap, void *old_ptr, size_t new_size)
 Reallocate memory.
void * realloc (void *old_ptr, size_t new_size)
 Reallocate memory.
void * malloc (size_t size)
 Allocate memory.
void free (void *ptr)
 Free memory.
void * zalloc (size_t size)
 Allocate cleared memory.
void zfree (void *ptr)
 Clear and free memory.
void * malloc_phys_offset (size_t size, size_t phys_align, size_t offset)
 Allocate memory with specified physical alignment and offset.
void * malloc_phys (size_t size, size_t phys_align)
 Allocate memory with specified physical alignment.
void free_phys (void *ptr, size_t size)
 Free memory allocated with malloc_phys().
void heap_populate (struct heap *heap, void *start, size_t len)
 Add memory to allocation pool.
static void init_heap (void)
 Initialise the heap.
struct init_fn heap_init_fn __init_fn (INIT_EARLY)
 Memory allocator initialisation function.
static void shutdown_cache (int booting __unused)
 Discard all cached data on shutdown.
struct startup_fn heap_startup_fn __startup_fn (STARTUP_EARLY)
 Memory allocator shutdown function.
void heap_dump (struct heap *heap)
 Dump free block list (for debugging).

Variables

static char heap_area [HEAP_SIZE]
 The heap area.
static struct heap heap
 The global heap.

Detailed Description

Dynamic memory allocation.

Memory allocation via malloc() is provided using a simple free-block list in a fixed-size heap.

The standard C semantics are supported. Calling realloc() with a size of zero is a valid way to free a block. Calling malloc() or realloc() with a size of zero will return a non-NULL value that can safely be passed to free() (meaning that callers can always treat a NULL return value as an error, without having to special-case a zero-length allocation).

(The POSIX semantics of setting a global errno variable on allocation failure are not supported: callers should check for a NULL return value and then return -ENOMEM as per the usual iPXE error propagation conventions.)

Memory allocation assumes that all input parameters are untrusted and must be checked. In particular, buffer sizes are frequently derived from untrusted input obtained via the network (e.g. an HTTP Content-Length header).

In contrast, memory deallocation assumes that the caller is always passing in a valid pointer value.

The internal heap is relatively small. Allocation is expected to sometimes fail in normal operation, and all callers must be prepared to handle it cleanly. Device drivers attempting to allocate receive buffers to refill a receive ring can simply exit the refill loop and do nothing until the next refill opportunity. Other callers will generally have to treat allocation failure as fatal and cleanly terminate their operation (e.g. by closing a connection).

The same internal heap supports both size-tracked allocations (using malloc()/free()) and known-size allocations (using malloc_phys()/free_phys(), where the caller must pass the original size when freeing the block). The latter are typically used for I/O buffers, driver descriptor rings, and other hardware-facing structures.

Depending upon the build platform, the underlying heap implementation may also be used to support external ("user") allocations using umalloc() and ufree().

A cache discard mechanism exists to attempt to alleviate memory pressure by discarding cached information (such as packets held in a TCP out-of-order receive queue) when an allocation attempt would otherwise fail. Code that holds pointers to discardable objects must be careful not to call any allocation functions.

Definition in file malloc.c.

Macro Definition Documentation

◆ MIN_MEMBLOCK_ALIGN

#define MIN_MEMBLOCK_ALIGN   ( 4 * sizeof ( void * ) )

Physical address alignment maintained for free blocks of memory.

We keep memory blocks aligned on a power of two that is at least large enough to hold a struct memory_block.

Definition at line 118 of file malloc.c.

Referenced by init_heap().

◆ HEAP_SIZE

#define HEAP_SIZE   ( 4096 * 1024 )

Heap area size.

Currently fixed at 4MB.

Definition at line 133 of file malloc.c.

◆ HEAP_ALIGN

#define HEAP_ALIGN   MIN_MEMBLOCK_ALIGN

Heap area alignment.

Definition at line 136 of file malloc.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ valgrind_make_blocks_defined()

void valgrind_make_blocks_defined ( struct heap * heap)
inlinestatic

Mark all blocks in free list as defined.

Parameters
heapHeap

Definition at line 146 of file malloc.c.

146 {
147 struct memory_block *block;
148
149 /* Do nothing unless running under Valgrind */
150 if ( RUNNING_ON_VALGRIND <= 0 )
151 return;
152
153 /* Traverse free block list, marking each block structure as
154 * defined. Some contortions are necessary to avoid errors
155 * from list_check().
156 */
157
158 /* Mark block list itself as defined */
160
161 /* Mark areas accessed by list_check() as defined */
163 sizeof ( heap->blocks.prev->next ) );
165 sizeof ( *heap->blocks.next ) );
167 sizeof ( heap->blocks.next->next->prev ) );
168
169 /* Mark each block in list as defined */
171
172 /* Mark block as defined */
173 VALGRIND_MAKE_MEM_DEFINED ( block, sizeof ( *block ) );
174
175 /* Mark areas accessed by list_check() as defined */
176 VALGRIND_MAKE_MEM_DEFINED ( block->list.next,
177 sizeof ( *block->list.next ) );
178 VALGRIND_MAKE_MEM_DEFINED ( &block->list.next->next->prev,
179 sizeof ( block->list.next->next->prev ) );
180 }
181}
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr, _qzz_len)
Definition memcheck.h:132
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
A heap.
Definition malloc.h:45
struct list_head blocks
List of free memory blocks.
Definition malloc.h:47
struct list_head * next
Next list entry.
Definition list.h:21
struct list_head * prev
Previous list entry.
Definition list.h:23
A free block of memory.
Definition malloc.c:95
struct list_head list
List of free blocks.
Definition malloc.c:110
#define RUNNING_ON_VALGRIND
Definition valgrind.h:4176

References block, heap::blocks, memory_block::list, list_for_each_entry, list_head::next, list_head::prev, RUNNING_ON_VALGRIND, and VALGRIND_MAKE_MEM_DEFINED.

Referenced by heap_alloc_block(), and heap_free_block().

◆ valgrind_make_blocks_noaccess()

void valgrind_make_blocks_noaccess ( struct heap * heap)
inlinestatic

Mark all blocks in free list as inaccessible.

Parameters
heapHeap

Definition at line 188 of file malloc.c.

188 {
189 struct memory_block *block;
190 struct memory_block *prev = NULL;
191
192 /* Do nothing unless running under Valgrind */
193 if ( RUNNING_ON_VALGRIND <= 0 )
194 return;
195
196 /* Traverse free block list, marking each block structure as
197 * inaccessible. Some contortions are necessary to avoid
198 * errors from list_check().
199 */
200
201 /* Mark each block in list as inaccessible */
203
204 /* Mark previous block (if any) as inaccessible. (Current
205 * block will be accessed by list_check().)
206 */
207 if ( prev )
208 VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) );
209 prev = block;
210
211 /* At the end of the list, list_check() will end up
212 * accessing the first list item. Temporarily mark
213 * this area as defined.
214 */
216 sizeof ( heap->blocks.next->prev ));
217 }
218 /* Mark last block (if any) as inaccessible */
219 if ( prev )
220 VALGRIND_MAKE_MEM_NOACCESS ( prev, sizeof ( *prev ) );
221
222 /* Mark as inaccessible the area that was temporarily marked
223 * as defined to avoid errors from list_check().
224 */
226 sizeof ( heap->blocks.next->prev ) );
227
228 /* Mark block list itself as inaccessible */
230}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr, _qzz_len)
Definition memcheck.h:112

References block, heap::blocks, memory_block::list, list_for_each_entry, list_head::next, NULL, list_head::prev, RUNNING_ON_VALGRIND, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by heap_alloc_block(), and heap_free_block().

◆ check_blocks()

void check_blocks ( struct heap * heap)
inlinestatic

Check integrity of the blocks in the free list.

Parameters
heapHeap

Definition at line 237 of file malloc.c.

237 {
238 struct memory_block *block;
239 struct memory_block *prev = NULL;
240
241 if ( ! ASSERTING )
242 return;
243
245
246 /* Check alignment */
247 assert ( ( virt_to_phys ( block ) &
248 ( heap->align - 1 ) ) == 0 );
249
250 /* Check that list structure is intact */
251 list_check ( &block->list );
252
253 /* Check that block size is not too small */
254 assert ( block->size >= sizeof ( *block ) );
255 assert ( block->size >= heap->align );
256
257 /* Check that block does not wrap beyond end of address space */
258 assert ( ( ( void * ) block + block->size ) >
259 ( ( void * ) block ) );
260
261 /* Check that blocks remain in ascending order, and
262 * that adjacent blocks have been merged.
263 */
264 if ( prev ) {
265 assert ( ( ( void * ) block ) > ( ( void * ) prev ) );
266 assert ( ( ( void * ) block ) >
267 ( ( ( void * ) prev ) + prev->size ) );
268 }
269 prev = block;
270 }
271}
#define ASSERTING
Definition assert.h:20
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
#define list_check(list)
Check a list entry or list head is valid.
Definition list.h:56
size_t align
Alignment for free memory blocks.
Definition malloc.h:50

References heap::align, assert, ASSERTING, block, heap::blocks, memory_block::list, list_check, list_for_each_entry, and NULL.

Referenced by heap_alloc_block(), and heap_free_block().

◆ discard_cache()

unsigned int discard_cache ( size_t size __unused)
static

Discard some cached data.

Parameters
sizeFailed allocation size
Return values
discardedNumber of cached items discarded

Definition at line 279 of file malloc.c.

279 {
280 struct cache_discarder *discarder;
281 unsigned int discarded;
282
284 discarded = discarder->discard();
285 if ( discarded )
286 return discarded;
287 }
288 return 0;
289}
#define CACHE_DISCARDERS
Cache discarder table.
Definition malloc.h:103
A cache discarder.
Definition malloc.h:93
unsigned int(* discard)(void)
Discard some cached data.
Definition malloc.h:99
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References __unused, CACHE_DISCARDERS, cache_discarder::discard, for_each_table_entry, and size.

Referenced by discard_all_cache().

◆ discard_all_cache()

void discard_all_cache ( void )
static

Discard all cached data.

Definition at line 295 of file malloc.c.

295 {
296 unsigned int discarded;
297
298 do {
299 discarded = discard_cache ( 0 );
300 } while ( discarded );
301}
static unsigned int discard_cache(size_t size __unused)
Discard some cached data.
Definition malloc.c:279

References discard_cache().

Referenced by shutdown_cache().

◆ heap_alloc_block()

void * heap_alloc_block ( struct heap * heap,
size_t size,
size_t align,
size_t offset )
static

Allocate a memory block.

Parameters
heapHeap
sizeRequested size
alignPhysical alignment
offsetOffset from physical alignment
Return values
ptrMemory block, or NULL

Allocates a memory block physically aligned as requested. No guarantees are provided for the alignment of the virtual address.

align must be a power of two. size may not be zero.

Definition at line 317 of file malloc.c.

318 {
319 struct memory_block *block;
320 size_t actual_offset;
321 size_t align_mask;
322 size_t actual_size;
323 size_t pre_size;
324 size_t post_size;
325 struct memory_block *pre;
326 struct memory_block *post;
327 unsigned int grown;
328 void *ptr;
329
330 /* Sanity checks */
332 check_blocks ( heap );
333
334 /* Validate inputs */
335 if ( ( size == 0 ) || ( align == 0 ) || ( align & ( align - 1 ) ) ) {
336 /* This is unreachable from any of our callers and
337 * could instead be an assertion, but we perform a
338 * runtime check anyway to guard against future
339 * possible code changes.
340 */
341 DBGC ( heap, "HEAP malformed allocation %#zx (aligned "
342 "%#zx+%#zx)\n", size, align, offset );
343 ptr = NULL;
344 goto done;
345 }
346
347 /* Limit offset to requested alignment */
348 offset &= ( align - 1 );
349
350 /* Calculate offset of memory block */
351 actual_offset = ( offset & ~( heap->align - 1 ) );
352 assert ( actual_offset <= offset );
353
354 /* Calculate size of memory block and check for overflow */
355 actual_size = ( ( size + offset - actual_offset + heap->align - 1 )
356 & ~( heap->align - 1 ) );
357 if ( actual_size < size ) {
358 ptr = NULL;
359 goto done;
360 }
361
362 /* Calculate alignment mask */
363 align_mask = ( ( align - 1 ) | ( heap->align - 1 ) );
364
365 DBGC2 ( heap, "HEAP allocating %#zx (aligned %#zx+%#zx)\n",
366 size, align, offset );
367 while ( 1 ) {
368 /* Search through blocks for the first one with enough space */
370 pre_size = ( ( actual_offset - virt_to_phys ( block ) )
371 & align_mask );
372 if ( ( block->size < pre_size ) ||
373 ( ( block->size - pre_size ) < actual_size ) )
374 continue;
375 post_size = ( block->size - pre_size - actual_size );
376 /* Split block into pre-block, block, and
377 * post-block. After this split, the "pre"
378 * block is the one currently linked into the
379 * free list.
380 */
381 pre = block;
382 block = ( ( ( void * ) pre ) + pre_size );
383 post = ( ( ( void * ) block ) + actual_size );
384 DBGC2 ( heap, "HEAP splitting [%p,%p) -> [%p,%p) "
385 "+ [%p,%p)\n", pre,
386 ( ( ( void * ) pre ) + pre->size ), pre, block,
387 post, ( ( ( void * ) pre ) + pre->size ) );
388 /* If there is a "post" block, add it in to
389 * the free list.
390 */
391 if ( post_size ) {
392 assert ( post_size >= sizeof ( *block ) );
393 assert ( ( post_size &
394 ( heap->align - 1 ) ) == 0 );
396 sizeof ( *post ));
397 post->size = post_size;
398 list_add ( &post->list, &pre->list );
399 }
400 /* Shrink "pre" block, leaving the main block
401 * isolated and no longer part of the free
402 * list.
403 */
404 pre->size = pre_size;
405 /* If there is no "pre" block, remove it from
406 * the list.
407 */
408 if ( ! pre_size ) {
409 list_del ( &pre->list );
411 sizeof ( *pre ) );
412 } else {
413 assert ( pre_size >= sizeof ( *block ) );
414 assert ( ( pre_size &
415 ( heap->align - 1 ) ) == 0 );
416 }
417 /* Update memory usage statistics */
418 heap->freemem -= actual_size;
419 heap->usedmem += actual_size;
420 if ( heap->usedmem > heap->maxusedmem )
422 /* Return allocated block */
423 ptr = ( ( ( void * ) block ) + offset - actual_offset );
424 DBGC2 ( heap, "HEAP allocated [%p,%p) within "
425 "[%p,%p)\n", ptr, ( ptr + size ), block,
426 ( ( ( void * ) block ) + actual_size ) );
428 goto done;
429 }
430
431 /* Attempt to grow heap to satisfy allocation */
432 DBGC ( heap, "HEAP attempting to grow for %#zx (aligned "
433 "%#zx+%zx), used %zdkB\n", size, align, offset,
434 ( heap->usedmem >> 10 ) );
436 grown = ( heap->grow ? heap->grow ( actual_size ) : 0 );
438 check_blocks ( heap );
439 if ( ! grown ) {
440 /* Heap did not grow: fail allocation */
441 DBGC ( heap, "HEAP failed to allocate %#zx (aligned "
442 "%#zx)\n", size, align );
443 ptr = NULL;
444 goto done;
445 }
446 }
447
448 done:
449 check_blocks ( heap );
451 return ptr;
452}
struct bofm_section_header done
Definition bofm_test.c:46
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define DBGC2(...)
Definition compiler.h:547
#define DBGC(...)
Definition compiler.h:530
uint16_t size
Buffer size.
Definition dwmac.h:3
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
static void valgrind_make_blocks_defined(struct heap *heap)
Mark all blocks in free list as defined.
Definition malloc.c:146
static void check_blocks(struct heap *heap)
Check integrity of the blocks in the free list.
Definition malloc.c:237
static void valgrind_make_blocks_noaccess(struct heap *heap)
Mark all blocks in free list as inaccessible.
Definition malloc.c:188
#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr, _qzz_len)
Definition memcheck.h:122
size_t usedmem
Total amount of used memory.
Definition malloc.h:57
size_t freemem
Total amount of free memory.
Definition malloc.h:55
unsigned int(* grow)(size_t size)
Attempt to grow heap (optional).
Definition malloc.h:67
size_t maxusedmem
Maximum amount of used memory.
Definition malloc.h:59
size_t size
Size of this block.
Definition malloc.c:97

References heap::align, assert, block, heap::blocks, check_blocks(), DBGC, DBGC2, done, heap::freemem, heap::grow, memory_block::list, list_add, list_del, list_for_each_entry, heap::maxusedmem, NULL, offset, memory_block::size, size, heap::usedmem, valgrind_make_blocks_defined(), valgrind_make_blocks_noaccess(), VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MAKE_MEM_UNDEFINED.

Referenced by heap_realloc(), and malloc_phys_offset().

◆ heap_free_block()

void heap_free_block ( struct heap * heap,
void * ptr,
size_t size )
static

Free a memory block.

Parameters
heapHeap
ptrMemory allocated by heap_alloc_block(), or NULL
sizeSize of the memory

If ptr is NULL, no action is taken.

Definition at line 463 of file malloc.c.

463 {
464 struct memory_block *freeing;
465 struct memory_block *block;
466 struct memory_block *tmp;
467 size_t sub_offset;
468 size_t actual_size;
469 ssize_t gap_before;
470 ssize_t gap_after = -1;
471
472 /* Allow for ptr==NULL */
473 if ( ! ptr )
474 return;
476
477 /* Sanity checks */
479 check_blocks ( heap );
480
481 /* Round up to match actual block that heap_alloc_block() would
482 * have allocated.
483 */
484 assert ( size != 0 );
485 sub_offset = ( virt_to_phys ( ptr ) & ( heap->align - 1 ) );
486 freeing = ( ptr - sub_offset );
487 actual_size = ( ( size + sub_offset + heap->align - 1 ) &
488 ~( heap->align - 1 ) );
489 DBGC2 ( heap, "HEAP freeing [%p,%p) within [%p,%p)\n",
490 ptr, ( ptr + size ), freeing,
491 ( ( ( void * ) freeing ) + actual_size ) );
492 VALGRIND_MAKE_MEM_UNDEFINED ( freeing, sizeof ( *freeing ) );
493
494 /* Check that this block does not overlap the free list */
495 if ( ASSERTING ) {
497 if ( ( ( ( void * ) block ) <
498 ( ( void * ) freeing + actual_size ) ) &&
499 ( ( void * ) freeing <
500 ( ( void * ) block + block->size ) ) ) {
501 assert ( 0 );
502 DBGC ( heap, "HEAP double free of [%p,%p) "
503 "overlapping [%p,%p) detected from %p\n",
504 freeing,
505 ( ( ( void * ) freeing ) + size ), block,
506 ( ( void * ) block + block->size ),
507 __builtin_return_address ( 0 ) );
508 }
509 }
510 }
511
512 /* Insert/merge into free list */
513 freeing->size = actual_size;
515 /* Calculate gaps before and after the "freeing" block */
516 gap_before = ( ( ( void * ) freeing ) -
517 ( ( ( void * ) block ) + block->size ) );
518 gap_after = ( ( ( void * ) block ) -
519 ( ( ( void * ) freeing ) + freeing->size ) );
520 /* Merge with immediately preceding block, if possible */
521 if ( gap_before == 0 ) {
522 DBGC2 ( heap, "HEAP merging [%p,%p) + [%p,%p) -> "
523 "[%p,%p)\n", block,
524 ( ( ( void * ) block ) + block->size ), freeing,
525 ( ( ( void * ) freeing ) + freeing->size ),
526 block,
527 ( ( ( void * ) freeing ) + freeing->size ) );
528 block->size += actual_size;
529 list_del ( &block->list );
531 sizeof ( *freeing ) );
532 freeing = block;
533 }
534 /* Stop processing as soon as we reach a following block */
535 if ( gap_after >= 0 )
536 break;
537 }
538
539 /* Insert before the immediately following block. If
540 * possible, merge the following block into the "freeing"
541 * block.
542 */
543 DBGC2 ( heap, "HEAP freed [%p,%p)\n",
544 freeing, ( ( ( void * ) freeing ) + freeing->size ) );
545 list_add_tail ( &freeing->list, &block->list );
546 if ( gap_after == 0 ) {
547 DBGC2 ( heap, "HEAP merging [%p,%p) + [%p,%p) -> [%p,%p)\n",
548 freeing, ( ( ( void * ) freeing ) + freeing->size ),
549 block, ( ( ( void * ) block ) + block->size ), freeing,
550 ( ( ( void * ) block ) + block->size ) );
551 freeing->size += block->size;
552 list_del ( &block->list );
553 VALGRIND_MAKE_MEM_NOACCESS ( block, sizeof ( *block ) );
554 }
555
556 /* Update memory usage statistics */
557 heap->freemem += actual_size;
558 heap->usedmem -= actual_size;
559
560 /* Allow heap to shrink */
561 if ( heap->shrink && heap->shrink ( freeing, freeing->size ) ) {
562 list_del ( &freeing->list );
563 heap->freemem -= freeing->size;
564 VALGRIND_MAKE_MEM_UNDEFINED ( freeing, freeing->size );
565 }
566
567 /* Sanity checks */
568 check_blocks ( heap );
570}
signed long ssize_t
Definition stdint.h:7
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
unsigned int(* shrink)(void *ptr, size_t size)
Allow heap to shrink (optional).
Definition malloc.h:79

References heap::align, assert, ASSERTING, block, heap::blocks, check_blocks(), DBGC, DBGC2, heap::freemem, memory_block::list, list_add_tail, list_del, list_for_each_entry, list_for_each_entry_safe, heap::shrink, memory_block::size, size, tmp, heap::usedmem, valgrind_make_blocks_defined(), valgrind_make_blocks_noaccess(), VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MAKE_MEM_UNDEFINED.

Referenced by free_phys(), heap_populate(), and heap_realloc().

◆ heap_realloc()

void * heap_realloc ( struct heap * heap,
void * old_ptr,
size_t new_size )

Reallocate memory.

Parameters
heapHeap
old_ptrMemory previously allocated by heap_realloc(), or NULL
new_sizeRequested size
Return values
new_ptrAllocated memory, or NULL

Allocates memory with no particular alignment requirement. new_ptr will be aligned to at least a multiple of sizeof(void*). If old_ptr is non-NULL, then the contents of the newly allocated memory will be the same as the contents of the previously allocated memory, up to the minimum of the old and new sizes. The old memory will be freed.

If allocation fails the previously allocated block is left untouched and NULL is returned.

Calling heap_realloc() with a new size of zero is a valid way to free a memory block.

Definition at line 593 of file malloc.c.

593 {
594 struct autosized_block *old_block;
595 struct autosized_block *new_block;
596 size_t old_total_size;
597 size_t new_total_size;
598 size_t old_size;
599 size_t offset = offsetof ( struct autosized_block, data );
600 void *new_ptr = NOWHERE;
601
602 /* Allocate new memory if necessary. If allocation fails,
603 * return without touching the old block.
604 */
605 if ( new_size ) {
606 new_total_size = ( new_size + offset );
607 if ( new_total_size < new_size )
608 return NULL;
609 new_block = heap_alloc_block ( heap, new_total_size,
610 heap->ptr_align, -offset );
611 if ( ! new_block )
612 return NULL;
613 new_block->size = new_total_size;
614 VALGRIND_MAKE_MEM_NOACCESS ( &new_block->size,
615 sizeof ( new_block->size ) );
616 new_ptr = &new_block->data;
617 VALGRIND_MALLOCLIKE_BLOCK ( new_ptr, new_size, 0, 0 );
618 assert ( ( ( ( intptr_t ) new_ptr ) &
619 ( heap->ptr_align - 1 ) ) == 0 );
620 }
621
622 /* Copy across relevant part of the old data region (if any),
623 * then free it. Note that at this point either (a) new_ptr
624 * is valid, or (b) new_size is 0; either way, the memcpy() is
625 * valid.
626 */
627 if ( old_ptr && ( old_ptr != NOWHERE ) ) {
628 old_block = container_of ( old_ptr, struct autosized_block,
629 data );
630 VALGRIND_MAKE_MEM_DEFINED ( &old_block->size,
631 sizeof ( old_block->size ) );
632 old_total_size = old_block->size;
633 assert ( old_total_size != 0 );
634 old_size = ( old_total_size - offset );
635 memcpy ( new_ptr, old_ptr,
636 ( ( old_size < new_size ) ? old_size : new_size ) );
637 VALGRIND_FREELIKE_BLOCK ( old_ptr, 0 );
638 heap_free_block ( heap, old_block, old_total_size );
639 }
640
641 if ( ASSERTED ) {
642 DBGC ( heap, "HEAP detected possible memory corruption "
643 "from %p\n", __builtin_return_address ( 0 ) );
644 }
645 return new_ptr;
646}
unsigned long intptr_t
Definition stdint.h:21
#define ASSERTED
Definition assert.h:26
uint8_t data[48]
Additional event data.
Definition ena.h:11
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void * heap_alloc_block(struct heap *heap, size_t size, size_t align, size_t offset)
Allocate a memory block.
Definition malloc.c:317
static void heap_free_block(struct heap *heap, void *ptr, size_t size)
Free a memory block.
Definition malloc.c:463
#define NOWHERE
Address for zero-length memory blocks.
Definition malloc.h:42
#define offsetof(type, field)
Get offset of a field within a structure.
Definition stddef.h:25
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A block of allocated memory complete with size information.
Definition malloc.c:121
size_t size
Size of this block.
Definition malloc.c:123
char data[0]
Remaining data.
Definition malloc.c:125
size_t ptr_align
Alignment for size-tracked allocations.
Definition malloc.h:52
#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)
Definition valgrind.h:4412
#define VALGRIND_FREELIKE_BLOCK(addr, rzB)
Definition valgrind.h:4422

References assert, ASSERTED, container_of, autosized_block::data, data, DBGC, heap_alloc_block(), heap_free_block(), memcpy(), NOWHERE, NULL, offset, offsetof, heap::ptr_align, autosized_block::size, VALGRIND_FREELIKE_BLOCK, VALGRIND_MAKE_MEM_DEFINED, VALGRIND_MAKE_MEM_NOACCESS, and VALGRIND_MALLOCLIKE_BLOCK.

Referenced by realloc(), and uheap_realloc().

◆ realloc()

void * realloc ( void * old_ptr,
size_t new_size )

Reallocate memory.

Parameters
old_ptrMemory previously allocated by malloc(), or NULL
new_sizeRequested size
Return values
new_ptrAllocated memory, or NULL

Definition at line 663 of file malloc.c.

663 {
664
665 return heap_realloc ( &heap, old_ptr, new_size );
666}
void * heap_realloc(struct heap *heap, void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:593

References heap_realloc().

Referenced by __attribute__(), asn1_grow(), bitmap_resize(), cachedhcp_record(), dhcpopt_init(), efi_ifr_op(), efi_ifr_string(), efivars_find(), free(), ibft_alloc_string(), ibft_install(), line_buffer(), malloc(), nvo_realloc(), process_script(), and xferbuf_malloc_realloc().

◆ malloc()

void * malloc ( size_t size)

Allocate memory.

Parameters
sizeRequested size
Return values
ptrMemory, or NULL

Allocates memory with no particular alignment requirement. ptr will be aligned to at least a multiple of sizeof(void*).

Definition at line 677 of file malloc.c.

677 {
678 void *ptr;
679
680 ptr = realloc ( NULL, size );
681 if ( ASSERTED ) {
682 DBGC ( &heap, "HEAP detected possible memory corruption "
683 "from %p\n", __builtin_return_address ( 0 ) );
684 }
685 return ptr;
686}
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:663

References ASSERTED, DBGC, NULL, realloc(), and size.

Referenced by add_tls(), aes_unwrap(), aes_wrap(), alloc_iob_raw(), apply_dns_search(), ath5k_hw_rfregs_init(), chap_init(), datauri_open(), deflate_test_exec(), der_asn1(), derwin(), dhcpv6_rx(), dupwin(), eap_rx_mschapv2_request(), eap_tx_response(), ecdsa_alloc(), efi_block_label(), efi_boot_path(), efi_cacert_all(), efi_download_start(), efi_load_path(), efi_local_check_volume_name(), efi_local_len(), efi_locate_device(), efi_vasprintf(), efivars_fetch(), eisabus_probe(), exchange_okx(), fc_ulp_login(), fetch_setting_copy(), ffdhe(), format_uri_alloc(), http_format_ntlm_auth(), icert_encode(), int13_hook(), ipair_rx_pubkey(), ipoib_map_remac(), ipv4_add_miniroute(), isabus_probe(), isapnpbus_probe(), iscsi_handle_chap_c_value(), iscsi_handle_chap_r_value(), iscsi_rx_buffered_data(), iscsi_scsi_command(), jme_alloc_rx_resources(), jme_alloc_tx_resources(), lldp_rx(), loopback_test(), mcabus_probe(), memcpy_test_speed(), mlx_memory_alloc_priv(), net80211_probe_start(), net80211_register(), newwin(), nfs_uri_symlink(), ntlm_authenticate_okx(), ocsp_response(), ocsp_uri_string(), parse_kv(), parse_net_args(), pci_vpd_resize(), pcibus_probe(), peerblk_decrypt(), peerblk_parse_header(), pem_asn1(), rsa_alloc(), sandev_parse_iso9660(), slirp_timer_new(), storef_setting(), storen_setting(), strndup(), t509bus_probe(), tls_new_session_ticket(), tls_send_client_key_exchange_dhe(), uhci_enqueue(), usb_config_descriptor(), usb_get_string_descriptor(), usbio_config(), usbio_path(), vasprintf(), vesafb_mode_list(), vmbus_open(), wpa_make_rsn_ie(), wpa_start(), and zalloc().

◆ free()

void free ( void * ptr)

Free memory.

Parameters
ptrMemory allocated by malloc(), or NULL

Memory allocated with malloc_phys() cannot be freed with free(); it must be freed with free_phys() instead.

If ptr is NULL, no action is taken.

Definition at line 698 of file malloc.c.

698 {
699
700 realloc ( ptr, 0 );
701 if ( ASSERTED ) {
702 DBGC ( &heap, "HEAP detected possible memory corruption "
703 "from %p\n", __builtin_return_address ( 0 ) );
704 }
705}

References ASSERTED, DBGC, and realloc().

◆ zalloc()

void * zalloc ( size_t size)

Allocate cleared memory.

Parameters
sizeRequested size
Return values
ptrAllocated memory

Allocate memory as per malloc(), and zero it.

This function name is non-standard, but pretty intuitive. zalloc(size) is always equivalent to calloc(1,size)

Definition at line 718 of file malloc.c.

718 {
719 void *data;
720
721 data = malloc ( size );
722 if ( data )
723 memset ( data, 0, size );
724 if ( ASSERTED ) {
725 DBGC ( &heap, "HEAP detected possible memory corruption "
726 "from %p\n", __builtin_return_address ( 0 ) );
727 }
728 return data;
729}
void * memset(void *dest, int character, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677

References ASSERTED, data, DBGC, malloc(), memset(), and size.

Referenced by add_dynui_item(), add_parameter(), alloc_form(), alloc_gpios(), alloc_ibdev(), alloc_image(), alloc_netdev(), alloc_pixbuf(), alloc_sandev(), alloc_uart(), alloc_usb(), alloc_usb_bus(), alloc_usb_hub(), aoecmd_create(), aoedev_open(), ar9300_eeprom_restore_internal(), arbel_alloc(), arbel_create_cq(), arbel_create_qp(), ata_open(), atadev_command(), ath5k_hw_attach(), ath5k_probe(), ath9k_init_softc(), ath_descdma_setup(), atl1e_setup_ring_resources(), autovivify_child_settings(), blob_open(), block_translate(), cachedhcp_record(), calloc(), cms_message(), cms_parse_participants(), concat_args(), cpio_okx(), create_downloader(), create_dynui(), create_parameters(), create_pinger(), create_validator(), dhcp_deliver(), dhcpv6_register(), dns_resolv(), dt_probe_node(), dwgpio_group_probe(), dwusb_probe(), efi_block_exec(), efi_block_install(), efi_cmdline_init(), efi_fcp_path(), efi_file_open_image(), efi_ib_srp_path(), efi_image_filepath(), efi_image_uripath(), efi_iscsi_path(), efi_local_open(), efi_netdev_path(), efi_path_uri(), efi_paths(), efi_pxe_install(), efi_snp_hii_fetch(), efi_snp_hii_install(), efi_snp_hii_process(), efi_snp_hii_store(), efi_snp_probe(), efi_uri_path(), efi_usb_install(), efi_usb_open(), efi_usb_path(), efi_usb_probe(), efidev_alloc(), efipci_start(), efivars_find(), ehci_endpoint_open(), ehci_probe(), ehci_ring_alloc(), eoib_create_peer(), exanic_probe(), fc_els_create(), fc_ns_query(), fc_peer_create(), fc_port_open(), fc_ulp_create(), fc_xchg_create(), fcpdev_open(), fcpdev_scsi_command(), fetch_string_setting_copy_alloc(), fetchf_setting_copy(), flexboot_nodnic_create_cq(), flexboot_nodnic_create_qp(), flexboot_nodnic_eth_open(), flexboot_nodnic_probe(), fragment_reassemble(), ftp_open(), generic_settings_store(), golan_alloc(), golan_create_cq(), golan_create_qp_aux(), guestinfo_fetch_type(), hermon_alloc(), hermon_create_cq(), hermon_create_qp(), http_connect(), http_open(), http_open_uri(), hub_probe(), hv_probe(), hvm_probe(), ib_cmrc_open(), ib_create_conn(), ib_create_cq(), ib_create_madx(), ib_create_mi(), ib_create_path(), ib_create_qp(), ib_mcast_attach(), ib_srp_open(), ibft_install(), icert_certs(), imux_probe(), init_mlx_utils(), ipair_create(), ipv6_add_miniroute(), iscsi_open(), linda_create_send_wq(), mlx_memory_zalloc_priv(), ndp_register_settings(), neighbour_create(), net80211_handle_mgmt(), net80211_prepare_assoc(), net80211_probe_start(), net80211_probe_step(), net80211_step_associate(), nfs_open(), nii_map(), numeric_resolv(), ocsp_check(), ocsp_uri_string(), open(), parse_uri(), pcibridge_probe(), peerblk_open(), peerdisc_create(), peerdisc_discovered(), peermux_filter(), ping_open(), png_pixbuf(), pxe_menu_parse(), qib7322_create_send_bufs(), qib7322_create_send_wq(), qib7322_probe(), rc80211_init(), resolv(), resolv_setting(), rtl818x_probe(), scsi_open(), scsidev_command(), sec80211_install(), sis190_mii_probe(), skge_probe(), skge_ring_alloc(), sky2_probe(), sky2_up(), slam_open(), srp_open(), srpdev_scsi_command(), start_dhcp(), start_dhcpv6(), start_ipv6conf(), start_ntp(), start_pxebs(), tcp_open(), tftp_core_open(), tg3_alloc_consistent(), tls_agree_ephemeral(), tls_session(), tls_set_cipher(), tls_set_digest(), txnic_bgx_probe(), txnic_pf_probe(), ucode_exec(), udp_open_common(), uhci_endpoint_open(), uhci_probe(), undipci_probe(), undirom_probe(), uri_dup(), usb_probe_all(), usbblk_probe(), usbio_endpoint_open(), usbio_interfaces(), usbio_interrupt_open(), usbio_start(), usbkbd_probe(), validator_start_download(), vmbus_probe(), vmbus_probe_channels(), vxge_hw_device_initialize(), x509_alloc_chain(), x509_append(), x509_certificate(), xcm_create(), xenbus_probe_device(), xenstore_response(), xfer_open_named_socket(), xhci_bus_open(), xhci_device_open(), xhci_endpoint_open(), xhci_probe(), xhci_ring_alloc(), xsigo_ib_probe(), xve_create(), and zlib_deflate().

◆ zfree()

void zfree ( void * ptr)

Clear and free memory.

Parameters
ptrMemory allocated by malloc(), or NULL

If ptr is NULL, no action is taken.

Definition at line 738 of file malloc.c.

738 {
739 struct autosized_block *block;
740
741 if ( ptr && ( ptr != NOWHERE ) ) {
742 block = container_of ( ptr, struct autosized_block, data );
744 sizeof ( block->size ) );
745 assert ( block->size >= sizeof ( *block ) );
746 memset ( ptr, 0, ( block->size - sizeof ( *block ) ) );
748 sizeof ( block->size ) );
749 }
750 free ( ptr );
751 if ( ASSERTED ) {
752 DBGC ( &heap, "HEAP detected possible memory corruption "
753 "from %p\n", __builtin_return_address ( 0 ) );
754 }
755}
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55

References assert, ASSERTED, block, container_of, data, DBGC, free, memset(), NOWHERE, VALGRIND_MAKE_MEM_DEFINED, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by aes_unwrap(), aes_wrap(), asn1_grow(), chap_finish(), cms_cipher_key(), ecdsa_free(), ffdhe(), free_tls(), free_tls_session(), privkey_apply_settings(), privkey_free(), rsa_free(), tls_agree_ephemeral(), tls_clear_cipher(), tls_clear_digest(), tls_new_finished(), tls_new_session_ticket(), tls_send_certificate_verify(), tls_send_client_key_exchange_dhe(), and tls_send_client_key_exchange_pubkey().

◆ malloc_phys_offset()

void * malloc_phys_offset ( size_t size,
size_t phys_align,
size_t offset )

Allocate memory with specified physical alignment and offset.

Parameters
sizeRequested size
alignPhysical alignment
offsetOffset from physical alignment
Return values
ptrMemory, or NULL

align must be a power of two. size may not be zero.

Definition at line 767 of file malloc.c.

767 {
768 void * ptr;
769
770 assert ( phys_align != 0 );
771 ptr = heap_alloc_block ( &heap, size, phys_align, offset );
772 if ( ptr && size ) {
773 assert ( ( ( virt_to_phys ( ptr ) ^ offset ) &
774 ( phys_align - 1 ) ) == 0 );
775 VALGRIND_MALLOCLIKE_BLOCK ( ptr, size, 0, 0 );
776 }
777 return ptr;
778}

References assert, heap_alloc_block(), offset, size, and VALGRIND_MALLOCLIKE_BLOCK.

Referenced by alloc_iob_raw(), and malloc_phys().

◆ malloc_phys()

void * malloc_phys ( size_t size,
size_t phys_align )

Allocate memory with specified physical alignment.

Parameters
sizeRequested size
alignPhysical alignment
Return values
ptrMemory, or NULL

align must be a power of two. size may not be zero.

Definition at line 789 of file malloc.c.

789 {
790
791 return malloc_phys_offset ( size, phys_align, 0 );
792}
void * malloc_phys_offset(size_t size, size_t phys_align, size_t offset)
Allocate memory with specified physical alignment and offset.
Definition malloc.c:767

References malloc_phys_offset(), and size.

Referenced by __vxge_hw_fifo_create(), __vxge_hw_ring_create(), a3c90x_setup_rx_ring(), a3c90x_setup_tx_ring(), arbel_alloc(), arbel_alloc_icm(), arbel_create_cq(), arbel_create_eq(), arbel_create_recv_wq(), arbel_create_send_wq(), ath5k_desc_alloc(), ath_descdma_setup(), atl1e_setup_ring_resources(), b44_init_rx_ring(), b44_init_tx_ring(), efx_hunt_alloc_special_buffer(), ehci_bus_open(), ehci_ring_alloc(), ena_create_admin(), ena_create_async(), ena_create_cq(), ena_create_sq(), ena_probe(), exanic_probe(), falcon_alloc_special_buffer(), golan_cmd_init(), golan_create_cq(), golan_create_eq(), golan_create_qp_aux(), hermon_alloc(), hermon_create_cq(), hermon_create_eq(), hermon_create_qp(), hv_alloc_message(), hv_alloc_pages(), hvm_map_hypercall(), icplus_create_ring(), ifec_net_open(), ifec_tx_setup(), igbvf_setup_rx_resources(), igbvf_setup_tx_resources(), jme_alloc_rx_resources(), jme_alloc_tx_resources(), legacy_probe(), linda_create_recv_wq(), linda_init_send(), mlx_memory_alloc_dma_priv(), myri10ge_net_open(), myson_create_ring(), natsemi_create_ring(), netfront_create_ring(), nv_init_rings(), pcnet32_setup_rx_resources(), pcnet32_setup_tx_resources(), phantom_create_rx_ctx(), phantom_create_tx_ctx(), phantom_open(), qib7322_create_recv_wq(), qib7322_init_send(), rhine_create_ring(), rtl818x_init_rx_ring(), rtl818x_init_tx_ring(), sis190_open(), skge_up(), sky2_probe(), sky2_up(), uhci_bus_open(), uhci_enqueue(), uhci_ring_alloc(), velocity_alloc_rings(), vmbus_open(), and vmxnet3_open().

◆ free_phys()

void free_phys ( void * ptr,
size_t size )

Free memory allocated with malloc_phys().

Parameters
ptrMemory allocated by malloc_phys(), or NULL
sizeSize 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 ptr is NULL, no action is taken.

Definition at line 805 of file malloc.c.

805 {
806
807 VALGRIND_FREELIKE_BLOCK ( ptr, 0 );
808 heap_free_block ( &heap, ptr, size );
809}

References heap_free_block(), size, and VALGRIND_FREELIKE_BLOCK.

Referenced by __vxge_hw_fifo_delete(), __vxge_hw_ring_delete(), a3c90x_free_rx_ring(), a3c90x_free_tx_ring(), alloc_iob_raw(), arbel_alloc(), arbel_alloc_icm(), arbel_create_cq(), arbel_create_eq(), arbel_create_qp(), arbel_create_recv_wq(), arbel_destroy_cq(), arbel_destroy_eq(), arbel_destroy_qp(), arbel_free(), arbel_free_icm(), ath5k_desc_alloc(), ath5k_desc_free(), ath_descdma_cleanup(), ath_descdma_setup(), atl1e_free_ring_resources(), b44_free_rx_ring(), b44_free_tx_ring(), b44_init_rx_ring(), b44_init_tx_ring(), efx_hunt_free_special_buffer(), ehci_bus_close(), ehci_bus_open(), ehci_ring_alloc(), ehci_ring_free(), ena_create_admin(), ena_create_async(), ena_create_cq(), ena_create_sq(), ena_destroy_admin(), ena_destroy_async(), ena_destroy_cq(), ena_destroy_sq(), ena_probe(), ena_remove(), exanic_probe(), exanic_remove(), falcon_free_special_buffer(), free_iob(), golan_cmd_init(), golan_cmd_uninit(), golan_create_cq(), golan_create_eq(), golan_create_qp_aux(), golan_destory_eq(), golan_destroy_cq(), golan_destroy_qp(), hermon_alloc(), hermon_create_cq(), hermon_create_eq(), hermon_create_qp(), hermon_destroy_cq(), hermon_destroy_eq(), hermon_destroy_qp(), hermon_free(), hv_alloc_pages(), hv_free_message(), hv_free_pages(), hvm_unmap_hypercall(), icplus_create_ring(), icplus_destroy_ring(), ifec_free(), ifec_net_open(), igbvf_free_rx_resources(), igbvf_free_tx_resources(), jme_free_rx_resources(), jme_free_tx_resources(), legacy_probe(), legacy_remove(), linda_create_recv_wq(), linda_destroy_recv_wq(), linda_fini_send(), linda_init_send(), mlx_memory_free_dma_priv(), myri10ge_net_close(), myri10ge_net_open(), myson_create_ring(), myson_destroy_ring(), natsemi_create_ring(), natsemi_destroy_ring(), netfront_create_ring(), netfront_destroy_ring(), nv_free_rxtx_resources(), pcnet32_free_rx_resources(), pcnet32_free_tx_resources(), phantom_close(), phantom_create_rx_ctx(), phantom_create_tx_ctx(), phantom_open(), qib7322_create_recv_wq(), qib7322_destroy_recv_wq(), qib7322_fini_send(), qib7322_init_send(), rhine_destroy_ring(), rtl818x_free_rx_ring(), rtl818x_free_tx_ring(), sis190_free(), skge_free(), sky2_free_rings(), sky2_probe(), sky2_remove(), uhci_bus_close(), uhci_bus_open(), uhci_dequeue(), uhci_enqueue(), uhci_ring_alloc(), uhci_ring_free(), velocity_alloc_rings(), velocity_close(), vmbus_close(), vmbus_open(), vmxnet3_close(), and vmxnet3_open().

◆ heap_populate()

void heap_populate ( struct heap * heap,
void * start,
size_t len )

Add memory to allocation pool.

Parameters
heapHeap
startStart address
lenLength of memory

Adds a block of memory to the allocation pool. The memory must be aligned to the heap's required free memory block alignment.

Definition at line 821 of file malloc.c.

821 {
822
823 /* Sanity checks */
824 assert ( ( virt_to_phys ( start ) & ( heap->align - 1 ) ) == 0 );
825 assert ( ( len & ( heap->align - 1 ) ) == 0 );
826
827 /* Add to allocation pool */
829
830 /* Fix up memory usage statistics */
831 heap->usedmem += len;
832}
ring len
Length.
Definition dwmac.h:226
uint32_t start
Starting offset.
Definition netvsc.h:1

References heap::align, assert, heap_free_block(), len, start, and heap::usedmem.

Referenced by init_heap(), and uheap_grow().

◆ init_heap()

void init_heap ( void )
static

Initialise the heap.

Definition at line 838 of file malloc.c.

838 {
839
840 /* Sanity check */
841 build_assert ( MIN_MEMBLOCK_ALIGN >= sizeof ( struct memory_block ) );
842
843 /* Populate heap */
846 heap_populate ( &heap, heap_area, sizeof ( heap_area ) );
847}
#define build_assert(condition)
Assert a condition at build time (after dead code elimination).
Definition assert.h:88
static char heap_area[HEAP_SIZE]
The heap area.
Definition malloc.c:139
#define MIN_MEMBLOCK_ALIGN
Physical address alignment maintained for free blocks of memory.
Definition malloc.c:118
void heap_populate(struct heap *heap, void *start, size_t len)
Add memory to allocation pool.
Definition malloc.c:821

References heap::blocks, build_assert, heap_area, heap_populate(), MIN_MEMBLOCK_ALIGN, and VALGRIND_MAKE_MEM_NOACCESS.

Referenced by __init_fn().

◆ __init_fn()

struct init_fn heap_init_fn __init_fn ( INIT_EARLY )

Memory allocator initialisation function.

References __init_fn, INIT_EARLY, and init_heap().

◆ shutdown_cache()

void shutdown_cache ( int booting __unused)
static

Discard all cached data on shutdown.

Definition at line 859 of file malloc.c.

859 {
861 DBGC ( &heap, "HEAP maximum usage %zdkB\n",
862 ( heap.maxusedmem >> 10 ) );
863}
static void discard_all_cache(void)
Discard all cached data.
Definition malloc.c:295

References __unused, DBGC, discard_all_cache(), and heap::maxusedmem.

Referenced by __startup_fn().

◆ __startup_fn()

struct startup_fn heap_startup_fn __startup_fn ( STARTUP_EARLY )

Memory allocator shutdown function.

References __startup_fn, shutdown_cache(), and STARTUP_EARLY.

◆ heap_dump()

void heap_dump ( struct heap * heap)

Dump free block list (for debugging).

Definition at line 875 of file malloc.c.

875 {
876 struct memory_block *block;
877
878 dbg_printf ( "HEAP free block list:\n" );
880 dbg_printf ( "...[%p,%p] (size %#zx)\n", block,
881 ( ( ( void * ) block ) + block->size ),
882 block->size );
883 }
884}
void dbg_printf(const char *fmt,...)
Print debug message.
Definition debug.c:39

References block, heap::blocks, dbg_printf(), memory_block::list, and list_for_each_entry.

Variable Documentation

◆ heap_area

char heap_area[HEAP_SIZE]
static

The heap area.

Definition at line 139 of file malloc.c.

Referenced by init_heap().

◆ heap

struct heap heap
static
Initial value:
= {
.blocks = LIST_HEAD_INIT ( heap.blocks ),
.ptr_align = sizeof ( void * ),
}
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31

The global heap.

Definition at line 649 of file malloc.c.

649 {
650 .blocks = LIST_HEAD_INIT ( heap.blocks ),
651 .align = MIN_MEMBLOCK_ALIGN,
652 .ptr_align = sizeof ( void * ),
653 .grow = discard_cache,
654};