فهرست منبع

This should fix malloc with debug and without threads. (Chase N Douglas)
This should have been in r23660. Untested.

Bernhard Reutner-Fischer 16 سال پیش
والد
کامیت
0be050c8b6
6فایلهای تغییر یافته به همراه59 افزوده شده و 23 حذف شده
  1. 21 8
      libc/stdlib/malloc/free.c
  2. 5 0
      libc/stdlib/malloc/heap.h
  3. 6 6
      libc/stdlib/malloc/heap_debug.c
  4. 21 5
      libc/stdlib/malloc/malloc.c
  5. 2 0
      libc/stdlib/malloc/malloc.h
  6. 4 4
      libc/stdlib/malloc/realloc.c

+ 21 - 8
libc/stdlib/malloc/free.c

@@ -22,7 +22,11 @@ libc_hidden_proto(sbrk)
 #include "heap.h"
 #include "heap.h"
 
 
 static void
 static void
+#ifdef HEAP_USE_LOCKING
 free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)
 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;
   size_t size;
   struct heap_free_area *fa;
   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);
   size = MALLOC_SIZE (mem);
   mem = MALLOC_BASE (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.  */
   /* Put MEM back in the heap, and get the free-area it was placed in.  */
   fa = __heap_free (heap, mem, size);
   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.  */
      unmapped.  */
   if (HEAP_FREE_AREA_SIZE (fa) < MALLOC_UNMAP_THRESHOLD)
   if (HEAP_FREE_AREA_SIZE (fa) < MALLOC_UNMAP_THRESHOLD)
     /* Nope, nothing left to do, just release the lock.  */
     /* Nope, nothing left to do, just release the lock.  */
-    __pthread_mutex_unlock (heap_lock);
+    __heap_do_unlock (heap_lock);
   else
   else
     /* Yup, try to unmap FA.  */
     /* 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)",
 	  MALLOC_DEBUG (-1, "not unmapping: 0x%lx - 0x%lx (%ld bytes)",
 			start, end, end - start);
 			start, end, end - start);
 	  __malloc_unlock_sbrk ();
 	  __malloc_unlock_sbrk ();
-	  __pthread_mutex_unlock (heap_lock);
+	  __heap_do_unlock (heap_lock);
 	  return;
 	  return;
 	}
 	}
 #endif
 #endif
@@ -108,7 +112,7 @@ free_to_heap (void *mem, struct heap_free_area *heap, malloc_mutex_t *heap_lock)
 #ifdef MALLOC_USE_SBRK
 #ifdef MALLOC_USE_SBRK
 
 
       /* Release the heap lock; we're still holding the sbrk lock.  */
       /* Release the heap lock; we're still holding the sbrk lock.  */
-      __pthread_mutex_unlock (heap_lock);
+      __heap_do_unlock (heap_lock);
       /* Lower the brk.  */
       /* Lower the brk.  */
       sbrk (start - end);
       sbrk (start - end);
       /* Release the sbrk lock too; now we hold no locks.  */
       /* 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
 	      /* We have to unlock the heap before we recurse to free the mmb
 		 descriptor, because we might be unmapping from the mmb
 		 descriptor, because we might be unmapping from the mmb
 		 heap.  */
 		 heap.  */
-              __pthread_mutex_unlock (heap_lock);
+              __heap_do_unlock (heap_lock);
 
 
+#ifdef HEAP_USE_LOCKING
 	      /* Release the descriptor block we used.  */
 	      /* Release the descriptor block we used.  */
 	      free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
 	      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.  */
 	      /* Do the actual munmap.  */
 	      munmap ((void *)mmb_start, mmb_end - mmb_start);
 	      munmap ((void *)mmb_start, mmb_end - mmb_start);
 
 
-              __pthread_mutex_lock (heap_lock);
+              __heap_do_lock (heap_lock);
 
 
 #  ifdef __UCLIBC_HAS_THREADS__
 #  ifdef __UCLIBC_HAS_THREADS__
 	      /* In a multi-threaded program, it's possible that PREV_MMB has
 	      /* 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.  */
       /* Finally release the lock for good.  */
-      __pthread_mutex_unlock (heap_lock);
+      __heap_do_unlock (heap_lock);
 
 
       MALLOC_MMB_DEBUG_INDENT (-1);
       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.  */
       /* 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)
       if (unmap_end > unmap_start)
 	/* Finally, actually unmap the memory.  */
 	/* 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
 void
 free (void *mem)
 free (void *mem)
 {
 {
+#ifdef HEAP_USE_LOCKING
   free_to_heap (mem, __malloc_heap, &__malloc_heap_lock);
   free_to_heap (mem, __malloc_heap, &__malloc_heap_lock);
+#else
+  free_to_heap (mem, __malloc_heap);
+#endif
 }
 }

+ 5 - 0
libc/stdlib/malloc/heap.h

@@ -19,6 +19,11 @@
 # include <pthread.h>
 # include <pthread.h>
 # include <bits/uClibc_pthread.h>
 # include <bits/uClibc_pthread.h>
 # define HEAP_USE_LOCKING
 # 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
 #endif
 
 
 
 

+ 6 - 6
libc/stdlib/malloc/heap_debug.c

@@ -31,10 +31,10 @@ int __heap_debug = 0;
 
 
 
 
 static void
 static void
-__heap_dump_freelist (struct heap *heap)
+__heap_dump_freelist (struct heap_free_area *heap)
 {
 {
   struct heap_free_area *fa;
   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,
     __malloc_debug_printf (0,
 			   "0x%lx:  0x%lx - 0x%lx  (%d)\tP=0x%lx, N=0x%lx",
 			   "0x%lx:  0x%lx - 0x%lx  (%d)\tP=0x%lx, N=0x%lx",
 			   (long)fa,
 			   (long)fa,
@@ -47,7 +47,7 @@ __heap_dump_freelist (struct heap *heap)
 
 
 /* Output a text representation of HEAP to stderr, labelling it with STR.  */
 /* Output a text representation of HEAP to stderr, labelling it with STR.  */
 void
 void
-__heap_dump (struct heap *heap, const char *str)
+__heap_dump (struct heap_free_area *heap, const char *str)
 {
 {
   static smallint recursed;
   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
 /* Output an error message to stderr, and exit.  STR is printed with the
    failure message.  */
    failure message.  */
 static void attribute_noreturn
 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, ...)
 		      const char *str, char *fmt, ...)
 {
 {
   va_list val;
   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
 /* Do some consistency checks on HEAP.  If they fail, output an error
    message to stderr, and exit.  STR is printed with the failure message.  */
    message to stderr, and exit.  STR is printed with the failure message.  */
 void
 void
-__heap_check (struct heap *heap, const char *str)
+__heap_check (struct heap_free_area *heap, const char *str)
 {
 {
   typedef unsigned long ul_t;
   typedef unsigned long ul_t;
   struct heap_free_area *fa, *prev;
   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)
   if (first_fa && first_fa->prev)
     __heap_check_failure (heap, first_fa, str,
     __heap_check_failure (heap, first_fa, str,

+ 21 - 5
libc/stdlib/malloc/malloc.c

@@ -27,7 +27,9 @@ libc_hidden_proto(sbrk)
    programs can do a little mallocing without mmaping in more space.  */
    programs can do a little mallocing without mmaping in more space.  */
 HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
 HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
 struct heap_free_area *__malloc_heap = HEAP_INIT_WITH_FA (initial_fa);
 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;
 malloc_mutex_t __malloc_heap_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
 
 
 #if defined(MALLOC_USE_LOCKING) && defined(MALLOC_USE_SBRK)
 #if defined(MALLOC_USE_LOCKING) && defined(MALLOC_USE_SBRK)
 /* A lock protecting our use of sbrk.  */
 /* A lock protecting our use of sbrk.  */
@@ -45,12 +47,18 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;
    annoying ways.  */
    annoying ways.  */
 HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
 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);
 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;
 malloc_mutex_t __malloc_mmb_heap_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 #endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
 
 
 
 
 static void *
 static void *
+#ifdef HEAP_USE_LOCKING
 malloc_from_heap (size_t size, struct heap_free_area *heap, malloc_mutex_t *heap_lock)
 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;
   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.  */
   /* Include extra space to record the size of the allocated block.  */
   size += MALLOC_HEADER_SIZE;
   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.  */
   /* First try to get memory that's already in our heap.  */
   mem = __heap_alloc (heap, &size);
   mem = __heap_alloc (heap, &size);
 
 
-  __pthread_mutex_unlock (heap_lock);
+  __heap_do_unlock (heap_lock);
 
 
   if (unlikely (! mem))
   if (unlikely (! mem))
     /* We couldn't allocate from the heap, so grab some more
     /* 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);
 			(long)block, (long)block + block_size, block_size);
 
 
 	  /* Get back the heap lock.  */
 	  /* Get back the heap lock.  */
-	  __pthread_mutex_lock (heap_lock);
+	  __heap_do_lock (heap_lock);
 
 
 	  /* Put BLOCK into the heap.  */
 	  /* Put BLOCK into the heap.  */
 	  __heap_free (heap, block, block_size);
 	  __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.  */
 	  /* Try again to allocate.  */
 	  mem = __heap_alloc (heap, &size);
 	  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__)
 #if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
 	  /* Insert a record of BLOCK in sorted order into the
 	  /* 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)
 	    if (block < mmb->mem)
 	      break;
 	      break;
 
 
+#ifdef HEAP_USE_LOCKING
 	  new_mmb = malloc_from_heap (sizeof *new_mmb, __malloc_mmb_heap, &__malloc_mmb_heap_lock);
 	  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->next = mmb;
 	  new_mmb->mem = block;
 	  new_mmb->mem = block;
 	  new_mmb->size = block_size;
 	  new_mmb->size = block_size;
@@ -193,7 +205,7 @@ malloc (size_t size)
       __malloc_debug_init ();
       __malloc_debug_init ();
     }
     }
   if (__malloc_check)
   if (__malloc_check)
-    __heap_check (&__malloc_heap, "malloc");
+    __heap_check (__malloc_heap, "malloc");
 #endif
 #endif
 
 
 #ifdef __MALLOC_GLIBC_COMPAT__
 #ifdef __MALLOC_GLIBC_COMPAT__
@@ -209,7 +221,11 @@ malloc (size_t size)
   if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
   if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
     goto oom;
     goto oom;
 
 
+#ifdef HEAP_USE_LOCKING
   mem = malloc_from_heap (size, __malloc_heap, &__malloc_heap_lock);
   mem = malloc_from_heap (size, __malloc_heap, &__malloc_heap_lock);
+#else
+  mem = malloc_from_heap (size, __malloc_heap);
+#endif
   if (unlikely (!mem))
   if (unlikely (!mem))
     {
     {
     oom:
     oom:

+ 2 - 0
libc/stdlib/malloc/malloc.h

@@ -222,7 +222,9 @@ extern void __malloc_debug_printf (int indent, const char *fmt, ...);
 
 
 /* The malloc heap.  */
 /* The malloc heap.  */
 extern struct heap_free_area *__malloc_heap;
 extern struct heap_free_area *__malloc_heap;
+#ifdef __UCLIBC_HAS_THREADS__
 extern malloc_mutex_t __malloc_heap_lock;
 extern malloc_mutex_t __malloc_heap_lock;
 #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
 #ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
 extern malloc_mutex_t __malloc_mmb_heap_lock;
 extern malloc_mutex_t __malloc_mmb_heap_lock;
 #endif
 #endif
+#endif

+ 4 - 4
libc/stdlib/malloc/realloc.c

@@ -59,9 +59,9 @@ realloc (void *mem, size_t new_size)
     {
     {
       size_t extra = new_size - 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);
       extra = __heap_alloc_at (__malloc_heap, base_mem + size, extra);
-      __pthread_mutex_unlock (&__malloc_heap_lock);
+      __heap_do_unlock (&__malloc_heap_lock);
 
 
       if (extra)
       if (extra)
 	/* Record the changed size.  */
 	/* 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)
   else if (new_size + MALLOC_REALLOC_MIN_FREE_SIZE <= size)
     /* Shrink the block.  */
     /* 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);
       __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);
       MALLOC_SET_SIZE (base_mem, new_size);
     }
     }