summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-10-16 21:16:46 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-10-16 21:16:46 +0000
commit0be050c8b6579abd76f4a405a1964532d4e71bf1 (patch)
tree646250b525d2fc2116b54455cd3e1146ebf85e7f /libc
parent9674f4133f323e0d312a0e8f5ff3886c590f459e (diff)
This should fix malloc with debug and without threads. (Chase N Douglas)
This should have been in r23660. Untested.
Diffstat (limited to 'libc')
-rw-r--r--libc/stdlib/malloc/free.c29
-rw-r--r--libc/stdlib/malloc/heap.h5
-rw-r--r--libc/stdlib/malloc/heap_debug.c12
-rw-r--r--libc/stdlib/malloc/malloc.c26
-rw-r--r--libc/stdlib/malloc/malloc.h2
-rw-r--r--libc/stdlib/malloc/realloc.c8
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);
}