From 83cef9f931bcd2030f42079c332525e1e73ab6aa Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Tue, 23 Jul 2002 06:50:40 +0000 Subject: * Automatically try to unmap heap free-areas when they get very big. * Instead of using mmap/munmap directly for large allocations, just use the heap for everything (this is reasonable now that heap memory can be unmapped). * Use sbrk instead of mmap/munmap on systems with an MMU. --- libc/stdlib/malloc/heap.h | 70 ++++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 28 deletions(-) (limited to 'libc/stdlib/malloc/heap.h') diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h index 0d6465050..589bf42b0 100644 --- a/libc/stdlib/malloc/heap.h +++ b/libc/stdlib/malloc/heap.h @@ -29,10 +29,9 @@ typedef int heap_mutex_t; #endif - -/* The unit in which allocation is done, due to alignment constraints, etc. - All allocation requests are rounded up to a multiple of this size. - Must be a power of 2. */ +/* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY. + HEAP_GRANULARITY must be a power of 2. Malloc depends on this being the + same as MALLOC_ALIGNMENT. */ #define HEAP_GRANULARITY (sizeof (double)) @@ -40,10 +39,11 @@ typedef int heap_mutex_t; of memory can be allocated. */ struct heap { + /* A list of memory in the heap available for allocation. */ struct heap_free_area *free_areas; + heap_mutex_t lock; }; - #define HEAP_INIT { 0, HEAP_MUTEX_INIT } @@ -61,6 +61,8 @@ struct heap_free_area /* Return the address of the beginning of the frea area FA. FA is evaulated multiple times. */ #define HEAP_FREE_AREA_START(fa) ((void *)((char *)(fa + 1) - (fa)->size)) +/* Return the size of the frea area FA. */ +#define HEAP_FREE_AREA_SIZE(fa) ((fa)->size) /* Rounds SZ up to be a multiple of HEAP_GRANULARITY. */ @@ -74,6 +76,8 @@ struct heap_free_area (sizeof (struct heap_free_area) + HEAP_ADJUST_SIZE (1)) +/* Change this to `#if 1' to cause the heap routines to emit debugging info + to stderr. */ #if 0 #include static void HEAP_DEBUG (struct heap *heap, const char *str) @@ -81,18 +85,24 @@ static void HEAP_DEBUG (struct heap *heap, const char *str) static int recursed = 0; if (! recursed) { - struct heap_free_area *fa; + struct heap_free_area *fa, *prev; recursed = 1; fprintf (stderr, " %s: heap @0x%lx:\n", str, (long)heap); - for (fa = heap->free_areas; fa; fa = fa->next) - fprintf (stderr, - " 0x%lx: 0x%lx - 0x%lx (%d)\tN=0x%lx, P=0x%lx\n", - (long)fa, - (long)HEAP_FREE_AREA_START (fa), - (long)HEAP_FREE_AREA_END (fa), - fa->size, - (long)fa->prev, - (long)fa->next); + for (prev = 0, fa = heap->free_areas; fa; prev = fa, fa = fa->next) + { + fprintf (stderr, + " 0x%lx: 0x%lx - 0x%lx (%d)\tP=0x%lx, N=0x%lx\n", + (long)fa, + (long)HEAP_FREE_AREA_START (fa), + (long)HEAP_FREE_AREA_END (fa), + fa->size, + (long)fa->prev, + (long)fa->next); + if (fa->prev != prev) + fprintf (stderr, + " PREV POINTER CORRUPTED!!!! P=0x%lx should be 0x%lx\n", + (long)fa->prev, (long)prev); + } recursed = 0; } } @@ -101,6 +111,18 @@ static void HEAP_DEBUG (struct heap *heap, const char *str) #endif +/* Remove the free-area FA from HEAP. */ +extern inline void +__heap_unlink_free_area (struct heap *heap, struct heap_free_area *fa) +{ + if (fa->next) + fa->next->prev = fa->prev; + if (fa->prev) + fa->prev->next = fa->next; + else + heap->free_areas = fa->next; +} + /* Allocate SIZE bytes from the front of the free-area FA in HEAP, and return the amount actually allocated (which may be more than SIZE). */ extern inline size_t @@ -113,12 +135,7 @@ __heap_free_area_alloc (struct heap *heap, /* There's not enough room left over in FA after allocating the block, so just use the whole thing, removing it from the list of free areas. */ { - if (fa->next) - fa->next->prev = fa->prev; - if (fa->prev) - fa->prev->next = fa->next; - else - heap->free_areas = fa->next; + __heap_unlink_free_area (heap, fa); /* Remember that we've alloced the whole area. */ size = fa_size; } @@ -139,10 +156,7 @@ extern void *__heap_alloc (struct heap *heap, size_t *size); allocated, or 0 if we failed. */ extern size_t __heap_alloc_at (struct heap *heap, void *mem, size_t size); -/* Return the memory area MEM of size SIZE to HEAP. */ -extern void __heap_free (struct heap *heap, void *mem, size_t size); - -/* If the memory area MEM, of size SIZE, immediately follows an existing - free-area in HEAP, use it to extend that free-area, and return true; - otherwise return false. */ -extern int __heap_append_free (struct heap *heap, void *mem, size_t size); +/* Return the memory area MEM of size SIZE to HEAP. + Returns the heap free area into which the memory was placed. */ +extern struct heap_free_area *__heap_free (struct heap *heap, + void *mem, size_t size); -- cgit v1.2.3