From 306eedf9ae04d3bde9be48bda0d387432d530a73 Mon Sep 17 00:00:00 2001 From: Miles Bader Date: Wed, 9 Oct 2002 10:27:56 +0000 Subject: * Add support for uClinux's broken munmap, contingent on __UCLIBC_UCLINUX_BROKEN_MUNMAP__ (which is currently not defined anywhere). This makes other cases a tiny bit less efficient too. * Move the malloc lock into the heap structure (locking is still done at the malloc level though, not by the heap functions). * Initialize the malloc heap to contain a tiny initial static free-area so that programs that only do a very little allocation won't ever call mmap. --- libc/stdlib/malloc/heap.h | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'libc/stdlib/malloc/heap.h') diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h index d8e8335b6..42cde5227 100644 --- a/libc/stdlib/malloc/heap.h +++ b/libc/stdlib/malloc/heap.h @@ -14,6 +14,13 @@ #include +/* On multi-threaded systems, the heap includes a lock. */ +#ifdef __UCLIBC_HAS_THREADS__ +# include +# define HEAP_USE_LOCKING +#endif + + /* 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. */ @@ -26,9 +33,26 @@ struct heap { /* A list of memory in the heap available for allocation. */ struct heap_free_area *free_areas; + +#ifdef HEAP_USE_LOCKING + /* A lock that can be used by callers to control access to the heap. + The heap code _does not_ use this lock, it's merely here for the + convenience of users! */ + extern heap_mutex_t lock; +#endif }; -#define HEAP_INIT { 0 } +/* The HEAP_INIT macro can be used as a static initializer for a heap + variable. The HEAP_INIT_WITH_FA variant is used to initialize a heap + with an initial static free-area; its argument FA should be declared + using HEAP_DECLARE_STATIC_FREE_AREA. */ +#ifdef HEAP_USE_LOCKING +# define HEAP_INIT { 0, PTHREAD_MUTEX_INITIALIZER } +# define HEAP_INIT_WITH_FA(fa) { &fa._fa, PTHREAD_MUTEX_INITIALIZER } +#else +# define HEAP_INIT { 0 } +# define HEAP_INIT_WITH_FA(fa) { &fa._fa } +#endif /* A free-list area `header'. These are actually stored at the _ends_ of free areas (to make allocating from the beginning of the area simpler), @@ -47,6 +71,16 @@ struct heap_free_area /* Return the size of the frea area FA. */ #define HEAP_FREE_AREA_SIZE(fa) ((fa)->size) +/* This rather clumsy macro allows one to declare a static free-area for + passing to HEAP_INIT_WITH_FA initializer macro. This is only use for + which NAME is allowed. */ +#define HEAP_DECLARE_STATIC_FREE_AREA(name, size) \ + static struct \ + { \ + char space[(size) - sizeof (struct heap_free_area)]; \ + struct heap_free_area _fa; \ + } name = { "", { (size), 0, 0 } } + /* Rounds SZ up to be a multiple of HEAP_GRANULARITY. */ #define HEAP_ADJUST_SIZE(sz) \ @@ -97,6 +131,16 @@ extern void __heap_dump (struct heap *heap, const char *str); extern void __heap_check (struct heap *heap, const char *str); +#ifdef HEAP_USE_LOCKING +# define __heap_lock(heap) pthread_mutex_lock (&(heap)->lock) +# define __heap_unlock(heap) pthread_mutex_unlock (&(heap)->lock) +#else /* !__UCLIBC_HAS_THREADS__ */ +/* Without threads, mutex operations are a nop. */ +# define __heap_lock(heap) (void)0 +# define __heap_unlock(heap) (void)0 +#endif /* HEAP_USE_LOCKING */ + + /* Delete the free-area FA from HEAP. */ extern inline void __heap_delete (struct heap *heap, struct heap_free_area *fa) -- cgit v1.2.3