summaryrefslogtreecommitdiff
path: root/libc/stdlib/malloc/heap.h
diff options
context:
space:
mode:
authorMiles Bader <miles@lsi.nec.co.jp>2002-07-23 06:50:40 +0000
committerMiles Bader <miles@lsi.nec.co.jp>2002-07-23 06:50:40 +0000
commit83cef9f931bcd2030f42079c332525e1e73ab6aa (patch)
tree5867067ac5387998a301f69a59ca6d78b26680d5 /libc/stdlib/malloc/heap.h
parenta9752043dd652d0fb4addf947b76e57c588f430c (diff)
* 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.
Diffstat (limited to 'libc/stdlib/malloc/heap.h')
-rw-r--r--libc/stdlib/malloc/heap.h70
1 files changed, 42 insertions, 28 deletions
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 <stdio.h>
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);