diff options
| -rw-r--r-- | libc/stdlib/malloc/free.c | 29 | ||||
| -rw-r--r-- | libc/stdlib/malloc/heap.h | 5 | ||||
| -rw-r--r-- | libc/stdlib/malloc/heap_debug.c | 12 | ||||
| -rw-r--r-- | libc/stdlib/malloc/malloc.c | 26 | ||||
| -rw-r--r-- | libc/stdlib/malloc/malloc.h | 2 | ||||
| -rw-r--r-- | libc/stdlib/malloc/realloc.c | 8 | 
6 files changed, 59 insertions, 23 deletions
diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c index fd29690ad..4713b0624 100644 --- a/libc/stdlib/malloc/free.c +++ b/libc/stdlib/malloc/free.c @@ -22,7 +22,11 @@ libc_hidden_proto(sbrk)  #include "heap.h"  static void +#ifdef HEAP_USE_LOCKING  free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock) +#else +free_to_heap (void *mem, struct heap_free_area *heap) +#endif  {    size_t size;    struct heap_free_area *fa; @@ -39,7 +43,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)    size = MALLOC_SIZE (mem);    mem = MALLOC_BASE (mem); -  __pthread_mutex_lock (heap_lock); +  __heap_do_lock (heap_lock);    /* Put MEM back in the heap, and get the free-area it was placed in.  */    fa = __heap_free (heap, mem, size); @@ -48,7 +52,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)       unmapped.  */    if (HEAP_FREE_AREA_SIZE (fa) < MALLOC_UNMAP_THRESHOLD)      /* Nope, nothing left to do, just release the lock.  */ -    __pthread_mutex_unlock (heap_lock); +    __heap_do_unlock (heap_lock);    else      /* Yup, try to unmap FA.  */      { @@ -81,7 +85,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  	  MALLOC_DEBUG (-1, "not unmapping: 0x%lx - 0x%lx (%ld bytes)",  			start, end, end - start);  	  __malloc_unlock_sbrk (); -	  __pthread_mutex_unlock (heap_lock); +	  __heap_do_unlock (heap_lock);  	  return;  	}  #endif @@ -108,7 +112,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  #ifdef MALLOC_USE_SBRK        /* Release the heap lock; we're still holding the sbrk lock.  */ -      __pthread_mutex_unlock (heap_lock); +      __heap_do_unlock (heap_lock);        /* Lower the brk.  */        sbrk (start - end);        /* Release the sbrk lock too; now we hold no locks.  */ @@ -172,15 +176,20 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  	      /* We have to unlock the heap before we recurse to free the mmb  		 descriptor, because we might be unmapping from the mmb  		 heap.  */ -              __pthread_mutex_unlock (heap_lock); +              __heap_do_unlock (heap_lock); +#ifdef HEAP_USE_LOCKING  	      /* Release the descriptor block we used.  */  	      free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock); +#else +	      /* Release the descriptor block we used.  */ +              free_to_heap (mmb, &__malloc_mmb_heap); +#endif  	      /* Do the actual munmap.  */  	      munmap ((void *)mmb_start, mmb_end - mmb_start); -              __pthread_mutex_lock (heap_lock); +              __heap_do_lock (heap_lock);  #  ifdef __UCLIBC_HAS_THREADS__  	      /* In a multi-threaded program, it's possible that PREV_MMB has @@ -213,7 +222,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  	}        /* Finally release the lock for good.  */ -      __pthread_mutex_unlock (heap_lock); +      __heap_do_unlock (heap_lock);        MALLOC_MMB_DEBUG_INDENT (-1); @@ -243,7 +252,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  	}        /* Release the heap lock before we do the system call.  */ -      __pthread_mutex_unlock (heap_lock); +      __heap_do_unlock (heap_lock);        if (unmap_end > unmap_start)  	/* Finally, actually unmap the memory.  */ @@ -260,5 +269,9 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)  void  free (void *mem)  { +#ifdef HEAP_USE_LOCKING    free_to_heap (mem, __malloc_heap, &__malloc_heap_lock); +#else +  free_to_heap (mem, __malloc_heap); +#endif  } diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h index 8b05cded1..2a686b601 100644 --- a/libc/stdlib/malloc/heap.h +++ b/libc/stdlib/malloc/heap.h @@ -19,6 +19,11 @@  # include <pthread.h>  # include <bits/uClibc_pthread.h>  # define HEAP_USE_LOCKING +# define __heap_do_lock(heap_lock) __pthread_mutex_lock (heap_lock) +# define __heap_do_unlock(heap_lock) __pthread_mutex_unlock (heap_lock) +#else +# define __heap_do_lock(heap_lock) +# define __heap_do_unlock(heap_lock)  #endif diff --git a/libc/stdlib/malloc/heap_debug.c b/libc/stdlib/malloc/heap_debug.c index a2a9f4ec1..59a1780cd 100644 --- a/libc/stdlib/malloc/heap_debug.c +++ b/libc/stdlib/malloc/heap_debug.c @@ -31,10 +31,10 @@ int __heap_debug = 0;  static void -__heap_dump_freelist (struct heap *heap) +__heap_dump_freelist (struct heap_free_area *heap)  {    struct heap_free_area *fa; -  for (fa = heap->free_areas; fa; fa = fa->next) +  for (fa = heap; fa; fa = fa->next)      __malloc_debug_printf (0,  			   "0x%lx:  0x%lx - 0x%lx  (%d)\tP=0x%lx, N=0x%lx",  			   (long)fa, @@ -47,7 +47,7 @@ __heap_dump_freelist (struct heap *heap)  /* Output a text representation of HEAP to stderr, labelling it with STR.  */  void -__heap_dump (struct heap *heap, const char *str) +__heap_dump (struct heap_free_area *heap, const char *str)  {    static smallint recursed; @@ -69,7 +69,7 @@ __heap_dump (struct heap *heap, const char *str)  /* Output an error message to stderr, and exit.  STR is printed with the     failure message.  */  static void attribute_noreturn -__heap_check_failure (struct heap *heap, struct heap_free_area *fa, +__heap_check_failure (struct heap_free_area *heap, struct heap_free_area *fa,  		      const char *str, char *fmt, ...)  {    va_list val; @@ -95,11 +95,11 @@ __heap_check_failure (struct heap *heap, struct heap_free_area *fa,  /* Do some consistency checks on HEAP.  If they fail, output an error     message to stderr, and exit.  STR is printed with the failure message.  */  void -__heap_check (struct heap *heap, const char *str) +__heap_check (struct heap_free_area *heap, const char *str)  {    typedef unsigned long ul_t;    struct heap_free_area *fa, *prev; -  struct heap_free_area *first_fa = heap->free_areas; +  struct heap_free_area *first_fa = heap;    if (first_fa && first_fa->prev)      __heap_check_failure (heap, first_fa, str, diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c index 0caf012a2..d58d62d2d 100644 --- a/libc/stdlib/malloc/malloc.c +++ b/libc/stdlib/malloc/malloc.c @@ -27,7 +27,9 @@ libc_hidden_proto(sbrk)     programs can do a little mallocing without mmaping in more space.  */  HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);  struct heap_free_area *__malloc_heap = HEAP_INIT_WITH_FA (initial_fa); +#ifdef HEAP_USE_LOCKING  malloc_mutex_t __malloc_heap_lock = PTHREAD_MUTEX_INITIALIZER; +#endif  #if defined(MALLOC_USE_LOCKING) && defined(MALLOC_USE_SBRK)  /* A lock protecting our use of sbrk.  */ @@ -45,12 +47,18 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;     annoying ways.  */  HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */  struct heap_free_area *__malloc_mmb_heap = HEAP_INIT_WITH_FA (initial_mmb_fa); +#ifdef HEAP_USE_LOCKING  malloc_mutex_t __malloc_mmb_heap_lock = PTHREAD_MUTEX_INITIALIZER; +#endif  #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */  static void * +#ifdef HEAP_USE_LOCKING  malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap_lock) +#else +malloc_from_heap (size_t size, struct heap_free_area *heap) +#endif  {    void *mem; @@ -59,12 +67,12 @@ malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap    /* Include extra space to record the size of the allocated block.  */    size += MALLOC_HEADER_SIZE; -  __pthread_mutex_lock (heap_lock); +  __heap_do_lock (heap_lock);    /* First try to get memory that's already in our heap.  */    mem = __heap_alloc (heap, &size); -  __pthread_mutex_unlock (heap_lock); +  __heap_do_unlock (heap_lock);    if (unlikely (! mem))      /* We couldn't allocate from the heap, so grab some more @@ -128,7 +136,7 @@ malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap  			(long)block, (long)block + block_size, block_size);  	  /* Get back the heap lock.  */ -	  __pthread_mutex_lock (heap_lock); +	  __heap_do_lock (heap_lock);  	  /* Put BLOCK into the heap.  */  	  __heap_free (heap, block, block_size); @@ -138,7 +146,7 @@ malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap  	  /* Try again to allocate.  */  	  mem = __heap_alloc (heap, &size); -	  __pthread_mutex_unlock (heap_lock); +	  __heap_do_unlock (heap_lock);  #if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)  	  /* Insert a record of BLOCK in sorted order into the @@ -150,7 +158,11 @@ malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap  	    if (block < mmb->mem)  	      break; +#ifdef HEAP_USE_LOCKING  	  new_mmb = malloc_from_heap (sizeof *new_mmb, __malloc_mmb_heap, &__malloc_mmb_heap_lock); +#else +	  new_mmb = malloc_from_heap (sizeof *new_mmb, __malloc_mmb_heap); +#endif  	  new_mmb->next = mmb;  	  new_mmb->mem = block;  	  new_mmb->size = block_size; @@ -193,7 +205,7 @@ malloc (size_t size)        __malloc_debug_init ();      }    if (__malloc_check) -    __heap_check (&__malloc_heap, "malloc"); +    __heap_check (__malloc_heap, "malloc");  #endif  #ifdef __MALLOC_GLIBC_COMPAT__ @@ -209,7 +221,11 @@ malloc (size_t size)    if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))      goto oom; +#ifdef HEAP_USE_LOCKING    mem = malloc_from_heap (size, __malloc_heap, &__malloc_heap_lock); +#else +  mem = malloc_from_heap (size, __malloc_heap); +#endif    if (unlikely (!mem))      {      oom: diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h index f49ed34e3..4bad93276 100644 --- a/libc/stdlib/malloc/malloc.h +++ b/libc/stdlib/malloc/malloc.h @@ -222,7 +222,9 @@ extern void __malloc_debug_printf (int indent, const char *fmt, ...);  /* The malloc heap.  */  extern struct heap_free_area *__malloc_heap; +#ifdef __UCLIBC_HAS_THREADS__  extern malloc_mutex_t __malloc_heap_lock;  #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__  extern malloc_mutex_t __malloc_mmb_heap_lock;  #endif +#endif diff --git a/libc/stdlib/malloc/realloc.c b/libc/stdlib/malloc/realloc.c index b3b5bae14..f12123aa9 100644 --- a/libc/stdlib/malloc/realloc.c +++ b/libc/stdlib/malloc/realloc.c @@ -59,9 +59,9 @@ realloc (void *mem, size_t new_size)      {        size_t extra = new_size - size; -      __pthread_mutex_lock (&__malloc_heap_lock); +      __heap_do_lock (&__malloc_heap_lock);        extra = __heap_alloc_at (__malloc_heap, base_mem + size, extra); -      __pthread_mutex_unlock (&__malloc_heap_lock); +      __heap_do_unlock (&__malloc_heap_lock);        if (extra)  	/* Record the changed size.  */ @@ -82,9 +82,9 @@ realloc (void *mem, size_t new_size)    else if (new_size + MALLOC_REALLOC_MIN_FREE_SIZE <= size)      /* Shrink the block.  */      { -      __pthread_mutex_lock (&__malloc_heap_lock); +      __heap_do_lock (&__malloc_heap_lock);        __heap_free (__malloc_heap, base_mem + new_size, size - new_size); -      __pthread_mutex_unlock (&__malloc_heap_lock); +      __heap_do_unlock (&__malloc_heap_lock);        MALLOC_SET_SIZE (base_mem, new_size);      }  | 
