summaryrefslogtreecommitdiffstats
path: root/libc
diff options
context:
space:
mode:
Diffstat (limited to 'libc')
-rw-r--r--libc/stdlib/abort.c1
-rw-r--r--libc/stdlib/getpt.c28
-rw-r--r--libc/stdlib/grantpt.c5
-rw-r--r--libc/stdlib/malloc-simple/alloc.c3
-rw-r--r--libc/stdlib/malloc-standard/malloc.h1
-rw-r--r--libc/stdlib/malloc/free.c34
-rw-r--r--libc/stdlib/malloc/heap.h61
-rw-r--r--libc/stdlib/malloc/heap_alloc.c8
-rw-r--r--libc/stdlib/malloc/heap_alloc_at.c8
-rw-r--r--libc/stdlib/malloc/heap_debug.c12
-rw-r--r--libc/stdlib/malloc/heap_free.c8
-rw-r--r--libc/stdlib/malloc/malloc.c39
-rw-r--r--libc/stdlib/malloc/malloc.h12
-rw-r--r--libc/stdlib/malloc/memalign.c2
-rw-r--r--libc/stdlib/malloc/realloc.c8
-rw-r--r--libc/stdlib/stdlib.c46
16 files changed, 148 insertions, 128 deletions
diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c
index e2c9962f2..b71512f33 100644
--- a/libc/stdlib/abort.c
+++ b/libc/stdlib/abort.c
@@ -19,7 +19,6 @@ Cambridge, MA 02139, USA. */
/* Hacked up for uClibc by Erik Andersen */
#include <features.h>
-#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/libc/stdlib/getpt.c b/libc/stdlib/getpt.c
index 1b5de7c16..5b067438f 100644
--- a/libc/stdlib/getpt.c
+++ b/libc/stdlib/getpt.c
@@ -32,7 +32,6 @@ libc_hidden_proto(open)
libc_hidden_proto(close)
#if !defined __ASSUME_DEVPTS__
-# include <sys/statfs.h>
/* Constant that identifies the `devpts' filesystem. */
# define DEVPTS_SUPER_MAGIC 0x1cd1
@@ -75,14 +74,19 @@ posix_openpt (int flags)
/* Check that the /dev/pts filesystem is mounted
or if /dev is a devfs filesystem (this implies /dev/pts). */
- if ((_state & devpts_mounted)
- || (__libc_statfs (_PATH_DEVPTS, &fsbuf) == 0
+ if (
+#if !defined __UNIX98PTY_ONLY__
+ (_state & devpts_mounted) ||
+#endif
+ (__libc_statfs (_PATH_DEVPTS, &fsbuf) == 0
&& fsbuf.f_type == DEVPTS_SUPER_MAGIC)
|| (__libc_statfs (_PATH_DEV, &fsbuf) == 0
&& fsbuf.f_type == DEVFS_SUPER_MAGIC))
{
/* Everything is ok. */
+#if !defined __UNIX98PTY_ONLY__
_state |= devpts_mounted;
+#endif
return fd;
}
@@ -104,24 +108,24 @@ posix_openpt (int flags)
return -1;
}
}
+#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__
+ /* If we have no ptmx then ignore flags and use the fallback. */
+ if (_state & have_no_dev_ptmx)
+ return __bsd_getpt();
+#endif
return -1;
}
+libc_hidden_def(posix_openpt)
#undef have_no_dev_ptmx
#undef devpts_mounted
#if defined __USE_GNU && defined __UCLIBC_HAS_GETPT__
-int
-getpt (void)
+int getpt (void)
{
- int fd = posix_openpt(O_RDWR);
-#if !defined __UNIX98PTY_ONLY__
- if (fd == -1)
- fd = __bsd_getpt();
-#endif
- return fd;
+ return posix_openpt(O_RDWR);
}
-#if !defined __UNIX98PTY_ONLY__
+#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__
# define PTYNAME1 "pqrstuvwxyzabcde";
# define PTYNAME2 "0123456789abcdef";
diff --git a/libc/stdlib/grantpt.c b/libc/stdlib/grantpt.c
index b60ffe7dc..8c858506b 100644
--- a/libc/stdlib/grantpt.c
+++ b/libc/stdlib/grantpt.c
@@ -38,7 +38,8 @@ int __unix_grantpt (int fd);
/* Prototype for private function that gets the name of the slave
pseudo terminal in a safe way. */
static int pts_name (int fd, char **pts, size_t buf_len);
-
+extern __typeof(statfs) __libc_statfs;
+libc_hidden_proto(__libc_statfs)
#endif
/* Change the ownership and access permission of the slave pseudo
@@ -59,7 +60,7 @@ grantpt (attribute_unused int fd)
if (pts_name (fd, &buf, sizeof (_buf)))
return -1;
- if (statfs (buf, &fsbuf) < 0)
+ if (__libc_statfs (buf, &fsbuf) < 0)
return -1;
/* If the slave pseudo terminal lives on a `devpts' filesystem, the
diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c
index 13d4166a7..45faf62db 100644
--- a/libc/stdlib/malloc-simple/alloc.c
+++ b/libc/stdlib/malloc-simple/alloc.c
@@ -15,6 +15,7 @@
#include <string.h>
#include <errno.h>
#include <sys/mman.h>
+#include <malloc.h>
/* Experimentally off - libc_hidden_proto(memcpy) */
/*libc_hidden_proto(memset)*/
@@ -116,7 +117,7 @@ void free(void *ptr)
#ifdef L_memalign
#include <bits/uClibc_mutex.h>
-__UCLIBC_MUTEX_STATIC(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
+__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock)
#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock)
diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h
index e87d34758..e0f3658b7 100644
--- a/libc/stdlib/malloc-standard/malloc.h
+++ b/libc/stdlib/malloc-standard/malloc.h
@@ -23,7 +23,6 @@
#include <stdlib.h>
#include <sys/mman.h>
#include <bits/uClibc_mutex.h>
-#include <bits/libc-lock.h>
libc_hidden_proto(mmap)
libc_hidden_proto(sysconf)
diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c
index da395331b..91552919e 100644
--- a/libc/stdlib/malloc/free.c
+++ b/libc/stdlib/malloc/free.c
@@ -21,8 +21,18 @@ libc_hidden_proto(sbrk)
#include "malloc.h"
#include "heap.h"
+#ifdef HEAP_USE_LOCKING
+#define free_to_heap(mem, heap, lck) __free_to_heap(mem, heap, lck)
+#else
+#define free_to_heap(mem, heap, lck) __free_to_heap(mem, heap)
+#endif
+
static void
-free_to_heap (void *mem, struct heap *heap)
+__free_to_heap (void *mem, struct heap_free_area **heap
+#ifdef HEAP_USE_LOCKING
+ , malloc_mutex_t *heap_lock
+#endif
+ )
{
size_t size;
struct heap_free_area *fa;
@@ -39,7 +49,7 @@ free_to_heap (void *mem, struct heap *heap)
size = MALLOC_SIZE (mem);
mem = MALLOC_BASE (mem);
- __heap_lock (heap);
+ __heap_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 +58,7 @@ free_to_heap (void *mem, struct heap *heap)
unmapped. */
if (HEAP_FREE_AREA_SIZE (fa) < MALLOC_UNMAP_THRESHOLD)
/* Nope, nothing left to do, just release the lock. */
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
else
/* Yup, try to unmap FA. */
{
@@ -81,7 +91,7 @@ free_to_heap (void *mem, struct heap *heap)
MALLOC_DEBUG (-1, "not unmapping: 0x%lx - 0x%lx (%ld bytes)",
start, end, end - start);
__malloc_unlock_sbrk ();
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
return;
}
#endif
@@ -98,7 +108,7 @@ free_to_heap (void *mem, struct heap *heap)
another free area, even if it's smaller than
MALLOC_MIN_SIZE, will cause us not to reserve anything. */
{
- /* Put the reserved memory back in the heap; we asssume that
+ /* Put the reserved memory back in the heap; we assume that
MALLOC_UNMAP_THRESHOLD is greater than MALLOC_MIN_SIZE, so
we use the latter unconditionally here. */
__heap_free (heap, (void *)start, MALLOC_MIN_SIZE);
@@ -108,7 +118,7 @@ free_to_heap (void *mem, struct heap *heap)
#ifdef MALLOC_USE_SBRK
/* Release the heap lock; we're still holding the sbrk lock. */
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
/* Lower the brk. */
sbrk (start - end);
/* Release the sbrk lock too; now we hold no locks. */
@@ -172,15 +182,15 @@ free_to_heap (void *mem, struct heap *heap)
/* We have to unlock the heap before we recurse to free the mmb
descriptor, because we might be unmapping from the mmb
heap. */
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
/* Release the descriptor block we used. */
- free_to_heap (mmb, &__malloc_mmb_heap);
+ free_to_heap (mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
/* Do the actual munmap. */
munmap ((void *)mmb_start, mmb_end - mmb_start);
- __heap_lock (heap);
+ __heap_lock (heap_lock);
# ifdef __UCLIBC_HAS_THREADS__
/* In a multi-threaded program, it's possible that PREV_MMB has
@@ -213,7 +223,7 @@ free_to_heap (void *mem, struct heap *heap)
}
/* Finally release the lock for good. */
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
MALLOC_MMB_DEBUG_INDENT (-1);
@@ -243,7 +253,7 @@ free_to_heap (void *mem, struct heap *heap)
}
/* Release the heap lock before we do the system call. */
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
if (unmap_end > unmap_start)
/* Finally, actually unmap the memory. */
@@ -260,5 +270,5 @@ free_to_heap (void *mem, struct heap *heap)
void
free (void *mem)
{
- free_to_heap (mem, &__malloc_heap);
+ free_to_heap (mem, &__malloc_heap, &__malloc_heap_lock);
}
diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h
index 6505cd223..c0c5df821 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_lock(heap_lock) __pthread_mutex_lock (heap_lock)
+# define __heap_unlock(heap_lock) __pthread_mutex_unlock (heap_lock)
+#else
+# define __heap_lock(heap_lock)
+# define __heap_unlock(heap_lock)
#endif
@@ -29,32 +34,12 @@
#define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE))
-/* A heap is a collection of memory blocks, from which smaller blocks
- of memory can be allocated. */
-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! */
- pthread_mutex_t lock;
-#endif
-};
-
/* 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
+# define HEAP_INIT 0
+# define HEAP_INIT_WITH_FA(fa) &fa._fa
/* 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),
@@ -129,27 +114,23 @@ extern int __heap_debug;
#endif
/* Output a text representation of HEAP to stderr, labelling it with STR. */
-extern void __heap_dump (struct heap *heap, const char *str);
+extern void __heap_dump (struct heap_free_area *heap, const char *str);
/* Do some consistency checks on HEAP. If they fail, output an error
message to stderr, and exit. STR is printed with the failure message. */
-extern void __heap_check (struct heap *heap, const char *str);
-
-
-#define __heap_lock(heap) __pthread_mutex_lock (&(heap)->lock)
-#define __heap_unlock(heap) __pthread_mutex_unlock (&(heap)->lock)
+extern void __heap_check (struct heap_free_area *heap, const char *str);
/* Delete the free-area FA from HEAP. */
static __inline__ void
-__heap_delete (struct heap *heap, struct heap_free_area *fa)
+__heap_delete (struct heap_free_area **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;
+ *heap = fa->next;
}
@@ -157,7 +138,7 @@ __heap_delete (struct heap *heap, struct heap_free_area *fa)
HEAP. PREV and NEXT may be 0; if PREV is 0, FA is installed as the
first free-area. */
static __inline__ void
-__heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
+__heap_link_free_area (struct heap_free_area **heap, struct heap_free_area *fa,
struct heap_free_area *prev,
struct heap_free_area *next)
{
@@ -167,7 +148,7 @@ __heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
if (prev)
prev->next = fa;
else
- heap->free_areas = fa;
+ *heap = fa;
if (next)
next->prev = fa;
}
@@ -176,14 +157,14 @@ __heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
PREV may be 0, in which case FA is installed as the first free-area (but
FA may not be 0). */
static __inline__ void
-__heap_link_free_area_after (struct heap *heap,
+__heap_link_free_area_after (struct heap_free_area **heap,
struct heap_free_area *fa,
struct heap_free_area *prev)
{
if (prev)
prev->next = fa;
else
- heap->free_areas = fa;
+ *heap = fa;
fa->prev = prev;
}
@@ -192,7 +173,7 @@ __heap_link_free_area_after (struct heap *heap,
PREV and NEXT may be 0; if PREV is 0, MEM is installed as the first
free-area. */
static __inline__ struct heap_free_area *
-__heap_add_free_area (struct heap *heap, void *mem, size_t size,
+__heap_add_free_area (struct heap_free_area **heap, void *mem, size_t size,
struct heap_free_area *prev,
struct heap_free_area *next)
{
@@ -210,7 +191,7 @@ __heap_add_free_area (struct heap *heap, void *mem, size_t size,
/* 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). */
static __inline__ size_t
-__heap_free_area_alloc (struct heap *heap,
+__heap_free_area_alloc (struct heap_free_area **heap,
struct heap_free_area *fa, size_t size)
{
size_t fa_size = fa->size;
@@ -234,16 +215,16 @@ __heap_free_area_alloc (struct heap *heap,
/* Allocate and return a block at least *SIZE bytes long from HEAP.
*SIZE is adjusted to reflect the actual amount allocated (which may be
greater than requested). */
-extern void *__heap_alloc (struct heap *heap, size_t *size);
+extern void *__heap_alloc (struct heap_free_area **heap, size_t *size);
/* Allocate SIZE bytes at address MEM in HEAP. Return the actual size
allocated, or 0 if we failed. */
-extern size_t __heap_alloc_at (struct heap *heap, void *mem, size_t size);
+extern size_t __heap_alloc_at (struct heap_free_area **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,
+extern struct heap_free_area *__heap_free (struct heap_free_area **heap,
void *mem, size_t size);
/* Return true if HEAP contains absolutely no memory. */
-#define __heap_is_empty(heap) (! (heap)->free_areas)
+#define __heap_is_empty(heap) (! (heap))
diff --git a/libc/stdlib/malloc/heap_alloc.c b/libc/stdlib/malloc/heap_alloc.c
index 9f5fd6c1a..77b7d8560 100644
--- a/libc/stdlib/malloc/heap_alloc.c
+++ b/libc/stdlib/malloc/heap_alloc.c
@@ -20,7 +20,7 @@
*SIZE is adjusted to reflect the actual amount allocated (which may be
greater than requested). */
void *
-__heap_alloc (struct heap *heap, size_t *size)
+__heap_alloc (struct heap_free_area **heap, size_t *size)
{
struct heap_free_area *fa;
size_t _size = *size;
@@ -33,10 +33,10 @@ __heap_alloc (struct heap *heap, size_t *size)
we must make sure that every allocated block can hold one. */
_size = HEAP_ADJUST_SIZE (sizeof (struct heap_free_area));
- HEAP_DEBUG (heap, "before __heap_alloc");
+ HEAP_DEBUG (*heap, "before __heap_alloc");
/* Look for a free area that can contain _SIZE bytes. */
- for (fa = heap->free_areas; fa; fa = fa->next)
+ for (fa = *heap; fa; fa = fa->next)
if (fa->size >= _size)
{
/* Found one! */
@@ -45,7 +45,7 @@ __heap_alloc (struct heap *heap, size_t *size)
break;
}
- HEAP_DEBUG (heap, "after __heap_alloc");
+ HEAP_DEBUG (*heap, "after __heap_alloc");
return mem;
}
diff --git a/libc/stdlib/malloc/heap_alloc_at.c b/libc/stdlib/malloc/heap_alloc_at.c
index a65140fea..45d68598a 100644
--- a/libc/stdlib/malloc/heap_alloc_at.c
+++ b/libc/stdlib/malloc/heap_alloc_at.c
@@ -19,17 +19,17 @@
/* Allocate SIZE bytes at address MEM in HEAP. Return the actual size
allocated, or 0 if we failed. */
size_t
-__heap_alloc_at (struct heap *heap, void *mem, size_t size)
+__heap_alloc_at (struct heap_free_area **heap, void *mem, size_t size)
{
struct heap_free_area *fa;
size_t alloced = 0;
size = HEAP_ADJUST_SIZE (size);
- HEAP_DEBUG (heap, "before __heap_alloc_at");
+ HEAP_DEBUG (*heap, "before __heap_alloc_at");
/* Look for a free area that can contain SIZE bytes. */
- for (fa = heap->free_areas; fa; fa = fa->next)
+ for (fa = *heap; fa; fa = fa->next)
{
void *fa_mem = HEAP_FREE_AREA_START (fa);
if (fa_mem <= mem)
@@ -41,7 +41,7 @@ __heap_alloc_at (struct heap *heap, void *mem, size_t size)
}
}
- HEAP_DEBUG (heap, "after __heap_alloc_at");
+ HEAP_DEBUG (*heap, "after __heap_alloc_at");
return alloced;
}
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/heap_free.c b/libc/stdlib/malloc/heap_free.c
index 1c4634c55..15343c05a 100644
--- a/libc/stdlib/malloc/heap_free.c
+++ b/libc/stdlib/malloc/heap_free.c
@@ -18,12 +18,12 @@
/* Return the block of memory at MEM, of size SIZE, to HEAP. */
struct heap_free_area *
-__heap_free (struct heap *heap, void *mem, size_t size)
+__heap_free (struct heap_free_area **heap, void *mem, size_t size)
{
struct heap_free_area *fa, *prev_fa;
void *end = (char *)mem + size;
- HEAP_DEBUG (heap, "before __heap_free");
+ HEAP_DEBUG (*heap, "before __heap_free");
/* Find the right position in the free-list entry to place the new block.
This is the most speed critical loop in this malloc implementation:
@@ -32,7 +32,7 @@ __heap_free (struct heap *heap, void *mem, size_t size)
in the free-list when it becomes fragmented and long. [A better
implemention would use a balanced tree or something for the free-list,
though that bloats the code-size and complexity quite a bit.] */
- for (prev_fa = 0, fa = heap->free_areas; fa; prev_fa = fa, fa = fa->next)
+ for (prev_fa = 0, fa = *heap; fa; prev_fa = fa, fa = fa->next)
if (unlikely (HEAP_FREE_AREA_END (fa) >= mem))
break;
@@ -83,7 +83,7 @@ __heap_free (struct heap *heap, void *mem, size_t size)
/* Make the new block into a separate free-list entry. */
fa = __heap_add_free_area (heap, mem, size, prev_fa, fa);
- HEAP_DEBUG (heap, "after __heap_free");
+ HEAP_DEBUG (*heap, "after __heap_free");
return fa;
}
diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c
index ce74c5608..620a9fbcc 100644
--- a/libc/stdlib/malloc/malloc.c
+++ b/libc/stdlib/malloc/malloc.c
@@ -26,7 +26,10 @@ libc_hidden_proto(sbrk)
/* The malloc heap. We provide a bit of initial static space so that
programs can do a little mallocing without mmaping in more space. */
HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
-struct heap __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;
+#endif
#if defined(MALLOC_USE_LOCKING) && defined(MALLOC_USE_SBRK)
/* A lock protecting our use of sbrk. */
@@ -35,7 +38,7 @@ malloc_mutex_t __malloc_sbrk_lock;
#ifdef __UCLIBC_UCLINUX_BROKEN_MUNMAP__
-/* A list of all malloc_mmb structures describing blocsk that
+/* A list of all malloc_mmb structures describing blocks that
malloc has mmapped, ordered by the block address. */
struct malloc_mmb *__malloc_mmapped_blocks = 0;
@@ -43,12 +46,24 @@ struct malloc_mmb *__malloc_mmapped_blocks = 0;
them from the main heap, but that tends to cause heap fragmentation in
annoying ways. */
HEAP_DECLARE_STATIC_FREE_AREA (initial_mmb_fa, 48); /* enough for 3 mmbs */
-struct heap __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;
+#endif
#endif /* __UCLIBC_UCLINUX_BROKEN_MUNMAP__ */
+#ifdef HEAP_USE_LOCKING
+#define malloc_from_heap(size, heap, lck) __malloc_from_heap(size, heap, lck)
+#else
+#define malloc_from_heap(size, heap, lck) __malloc_from_heap(size, heap)
+#endif
static void *
-malloc_from_heap (size_t size, struct heap *heap)
+__malloc_from_heap (size_t size, struct heap_free_area **heap
+#ifdef HEAP_USE_LOCKING
+ , malloc_mutex_t *heap_lock
+#endif
+ )
{
void *mem;
@@ -57,12 +72,12 @@ malloc_from_heap (size_t size, struct heap *heap)
/* Include extra space to record the size of the allocated block. */
size += MALLOC_HEADER_SIZE;
- __heap_lock (heap);
+ __heap_lock (heap_lock);
/* First try to get memory that's already in our heap. */
mem = __heap_alloc (heap, &size);
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
if (unlikely (! mem))
/* We couldn't allocate from the heap, so grab some more
@@ -122,11 +137,11 @@ malloc_from_heap (size_t size, struct heap *heap)
struct malloc_mmb *mmb, *prev_mmb, *new_mmb;
#endif
- MALLOC_DEBUG (1, "adding system memroy to heap: 0x%lx - 0x%lx (%d bytes)",
+ MALLOC_DEBUG (1, "adding system memory to heap: 0x%lx - 0x%lx (%d bytes)",
(long)block, (long)block + block_size, block_size);
/* Get back the heap lock. */
- __heap_lock (heap);
+ __heap_lock (heap_lock);
/* Put BLOCK into the heap. */
__heap_free (heap, block, block_size);
@@ -136,7 +151,7 @@ malloc_from_heap (size_t size, struct heap *heap)
/* Try again to allocate. */
mem = __heap_alloc (heap, &size);
- __heap_unlock (heap);
+ __heap_unlock (heap_lock);
#if !defined(MALLOC_USE_SBRK) && defined(__UCLIBC_UCLINUX_BROKEN_MUNMAP__)
/* Insert a record of BLOCK in sorted order into the
@@ -148,7 +163,7 @@ malloc_from_heap (size_t size, struct heap *heap)
if (block < mmb->mem)
break;
- new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap);
+ new_mmb = malloc_from_heap (sizeof *new_mmb, &__malloc_mmb_heap, &__malloc_mmb_heap_lock);
new_mmb->next = mmb;
new_mmb->mem = block;
new_mmb->size = block_size;
@@ -191,7 +206,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__
@@ -207,7 +222,7 @@ malloc (size_t size)
if (unlikely(((unsigned long)size > (unsigned long)(MALLOC_HEADER_SIZE*-2))))
goto oom;
- mem = malloc_from_heap (size, &__malloc_heap);
+ mem = malloc_from_heap (size, &__malloc_heap, &__malloc_heap_lock);
if (unlikely (!mem))
{
oom:
diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h
index 7277cd2cf..2afc3a805 100644
--- a/libc/stdlib/malloc/malloc.h
+++ b/libc/stdlib/malloc/malloc.h
@@ -70,14 +70,14 @@ struct malloc_mmb
struct malloc_mmb *next;
};
-/* A list of all malloc_mmb structures describing blocsk that malloc has
+/* A list of all malloc_mmb structures describing blocks that malloc has
mmapped, ordered by the block address. */
extern struct malloc_mmb *__malloc_mmapped_blocks;
/* A heap used for allocating malloc_mmb structures. We could allocate
them from the main heap, but that tends to cause heap fragmentation in
annoying ways. */
-extern struct heap __malloc_mmb_heap;
+extern struct heap_free_area *__malloc_mmb_heap;
/* Define MALLOC_MMB_DEBUGGING to cause malloc to emit debugging info about
about mmap block allocation/freeing by the `uclinux broken munmap' code
@@ -221,4 +221,10 @@ extern void __malloc_debug_printf (int indent, const char *fmt, ...);
/* The malloc heap. */
-extern struct heap __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/memalign.c b/libc/stdlib/malloc/memalign.c
index 5b248f3e2..6826d623a 100644
--- a/libc/stdlib/malloc/memalign.c
+++ b/libc/stdlib/malloc/memalign.c
@@ -36,7 +36,7 @@ memalign (size_t alignment, size_t size)
{
void *mem, *base;
unsigned long tot_addr, tot_end_addr, addr, end_addr;
- struct heap *heap = &__malloc_heap;
+ struct heap_free_area **heap = &__malloc_heap;
/* Make SIZE something we like. */
size = HEAP_ADJUST_SIZE (size);
diff --git a/libc/stdlib/malloc/realloc.c b/libc/stdlib/malloc/realloc.c
index 948326762..a8271995b 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;
- __heap_lock (&__malloc_heap);
+ __heap_lock (&__malloc_heap_lock);
extra = __heap_alloc_at (&__malloc_heap, base_mem + size, extra);
- __heap_unlock (&__malloc_heap);
+ __heap_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. */
{
- __heap_lock (&__malloc_heap);
+ __heap_lock (&__malloc_heap_lock);
__heap_free (&__malloc_heap, base_mem + new_size, size - new_size);
- __heap_unlock (&__malloc_heap);
+ __heap_unlock (&__malloc_heap_lock);
MALLOC_SET_SIZE (base_mem, new_size);
}
diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c
index 0ebe3b9f9..3c74be71a 100644
--- a/libc/stdlib/stdlib.c
+++ b/libc/stdlib/stdlib.c
@@ -65,7 +65,7 @@
#ifdef L_wcstoul
#define wcstoull __ignore_wcstoull
#endif
-#ifdef strtol_l
+#ifdef L_strtol_l
#define strtoll_l __ignore_strtoll_l
#endif
#ifdef L_strtoul_l
@@ -344,7 +344,7 @@ strong_alias(strtol,strtoimax)
#else
#undef strtoll
#endif
-extern __typeof(strtol) __XL_NPP(strtoll);
+extern __typeof(__XL_NPP(strtol)) __XL_NPP(strtoll);
libc_hidden_proto(__XL_NPP(strtoll))
strong_alias(__XL_NPP(strtol),__XL_NPP(strtoll))
libc_hidden_def(__XL_NPP(strtoll))
@@ -397,7 +397,7 @@ strong_alias(strtoul,strtoumax)
#else
#undef strtoull
#endif
-extern __typeof(strtoul) __XL_NPP(strtoull);
+extern __typeof(__XL_NPP(strtoul)) __XL_NPP(strtoull);
libc_hidden_proto(__XL_NPP(strtoull))
strong_alias(__XL_NPP(strtoul),__XL_NPP(strtoull))
libc_hidden_def(__XL_NPP(strtoull))
@@ -931,15 +931,14 @@ libc_hidden_def(_stdlib_mb_cur_max)
#endif
#ifdef __UCLIBC_HAS_LOCALE__
-/*
+/*
* The following function return 1 if the encoding is stateful, 0 if stateless.
* To note, until now all the supported encoding are stateless.
*/
-
-static inline int
-is_stateful(unsigned char encoding)
+
+static __always_inline int is_stateful(unsigned char encoding)
{
- switch (encoding)
+ switch (encoding)
{
case __ctype_encoding_7_bit:
case __ctype_encoding_utf8:
@@ -966,16 +965,17 @@ int mblen(register const char *s, size_t n)
if (!s) {
state.__mask = 0;
-/* In this case we have to return 0 because the only multibyte supported encoding
- is utf-8, that is a stateless encoding. See mblen() documentation.*/
-
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See mblen() documentation.
+ */
return is_stateful(ENCODING);
}
if (*s == '\0')
- /* According to the ISO C 89 standard this is the expected behaviour. */
+ /* According to the ISO C 89 standard this is the expected behaviour. */
return 0;
-
+
if ((r = mbrlen(s, n, &state)) == (size_t) -2) {
/* TODO: Should we set an error state? */
state.__wc = 0xffffU; /* Make sure we're in an error state. */
@@ -997,16 +997,18 @@ int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n)
if (!s) {
state.__mask = 0;
-/* In this case we have to return 0 because the only multibyte supported encoding
- is utf-8, that is a stateless encoding. See mbtowc() documentation.*/
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See mbtowc() documentation.
+ */
return is_stateful(ENCODING);
}
if (*s == '\0')
- /* According to the ISO C 89 standard this is the expected behaviour. */
+ /* According to the ISO C 89 standard this is the expected behaviour. */
return 0;
-
+
if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) {
/* TODO: Should we set an error state? */
state.__wc = 0xffffU; /* Make sure we're in an error state. */
@@ -1027,8 +1029,10 @@ int wctomb(register char *__restrict s, wchar_t swc)
{
return (!s)
?
-/* In this case we have to return 0 because the only multibyte supported encoding
- is utf-8, that is a stateless encoding. See wctomb() documentation.*/
+ /*
+ In this case we have to return 0 because the only multibyte supported encoding
+ is utf-8, that is a stateless encoding. See wctomb() documentation.
+ */
is_stateful(ENCODING)
: ((ssize_t) wcrtomb(s, swc, NULL));
@@ -1086,7 +1090,7 @@ strong_alias(wcstol,wcstoimax)
#else
#undef wcstoll
#endif
-extern __typeof(wcstol) __XL_NPP(wcstoll);
+extern __typeof(__XL_NPP(wcstol)) __XL_NPP(wcstoll);
libc_hidden_proto(__XL_NPP(wcstoll))
strong_alias(__XL_NPP(wcstol),__XL_NPP(wcstoll))
libc_hidden_def(__XL_NPP(wcstoll))
@@ -1139,7 +1143,7 @@ strong_alias(wcstoul,wcstoumax)
#else
#undef wcstoull
#endif
-extern __typeof(wcstoul) __XL_NPP(wcstoull);
+extern __typeof(__XL_NPP(wcstoul)) __XL_NPP(wcstoull);
libc_hidden_proto(__XL_NPP(wcstoull))
strong_alias(__XL_NPP(wcstoul),__XL_NPP(wcstoull))
libc_hidden_def(__XL_NPP(wcstoull))