aboutsummaryrefslogtreecommitdiff
path: root/malloc
diff options
context:
space:
mode:
Diffstat (limited to 'malloc')
-rw-r--r--malloc/arena.c81
-rw-r--r--malloc/hooks.c26
-rw-r--r--malloc/malloc.c11
3 files changed, 111 insertions, 7 deletions
diff --git a/malloc/arena.c b/malloc/arena.c
index 090e3c1..27d2d9e 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -136,6 +136,11 @@ int __malloc_initialized = -1;
static __malloc_ptr_t (*save_malloc_hook) __MALLOC_P ((size_t __size,
__const __malloc_ptr_t));
+# if !defined _LIBC || !defined USE_TLS || (defined SHARED && !USE___THREAD)
+static __malloc_ptr_t (*save_memalign_hook) __MALLOC_P ((size_t __align,
+ size_t __size,
+ __const __malloc_ptr_t));
+# endif
static void (*save_free_hook) __MALLOC_P ((__malloc_ptr_t __ptr,
__const __malloc_ptr_t));
static Void_t* save_arena;
@@ -322,6 +327,51 @@ next_env_entry (char ***position)
}
#endif /* _LIBC */
+/* Set up basic state so that _int_malloc et al can work. */
+static void
+ptmalloc_init_minimal __MALLOC_P((void))
+{
+#if DEFAULT_TOP_PAD != 0
+ mp_.top_pad = DEFAULT_TOP_PAD;
+#endif
+ mp_.n_mmaps_max = DEFAULT_MMAP_MAX;
+ mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+ mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
+ mp_.pagesize = malloc_getpagesize;
+}
+
+#ifdef _LIBC
+# if defined SHARED && defined USE_TLS && !USE___THREAD
+# include <stdbool.h>
+
+/* This is called by __pthread_initialize_minimal when it needs to use
+ malloc to set up the TLS state. We cannot do the full work of
+ ptmalloc_init (below) until __pthread_initialize_minimal has finished,
+ so it has to switch to using the special startup-time hooks while doing
+ those allocations. */
+void
+__libc_malloc_pthread_startup (bool first_time)
+{
+ if (first_time)
+ {
+ ptmalloc_init_minimal ();
+ save_malloc_hook = __malloc_hook;
+ save_memalign_hook = __memalign_hook;
+ save_free_hook = __free_hook;
+ __malloc_hook = malloc_starter;
+ __memalign_hook = memalign_starter;
+ __free_hook = free_starter;
+ }
+ else
+ {
+ __malloc_hook = save_malloc_hook;
+ __memalign_hook = save_memalign_hook;
+ __free_hook = save_free_hook;
+ }
+}
+# endif
+#endif
+
static void
ptmalloc_init __MALLOC_P((void))
{
@@ -335,25 +385,37 @@ ptmalloc_init __MALLOC_P((void))
if(__malloc_initialized >= 0) return;
__malloc_initialized = 0;
- mp_.top_pad = DEFAULT_TOP_PAD;
- mp_.n_mmaps_max = DEFAULT_MMAP_MAX;
- mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
- mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
- mp_.pagesize = malloc_getpagesize;
+#ifdef _LIBC
+# if defined SHARED && defined USE_TLS && !USE___THREAD
+ /* ptmalloc_init_minimal may already have been called via
+ __libc_malloc_pthread_startup, above. */
+ if (mp_.pagesize == 0)
+# endif
+#endif
+ ptmalloc_init_minimal();
#ifndef NO_THREADS
+# if defined _LIBC && defined USE_TLS
+ /* We know __pthread_initialize_minimal has already been called,
+ and that is enough. */
+# define NO_STARTER
+# endif
+# ifndef NO_STARTER
/* With some threads implementations, creating thread-specific data
or initializing a mutex may call malloc() itself. Provide a
simple starter version (realloc() won't work). */
save_malloc_hook = __malloc_hook;
+ save_memalign_hook = __memalign_hook;
save_free_hook = __free_hook;
__malloc_hook = malloc_starter;
+ __memalign_hook = memalign_starter;
__free_hook = free_starter;
-#ifdef _LIBC
+# ifdef _LIBC
/* Initialize the pthreads interface. */
if (__pthread_initialize != NULL)
__pthread_initialize();
-#endif
+# endif /* !defined _LIBC */
+# endif /* !defined NO_STARTER */
#endif /* !defined NO_THREADS */
mutex_init(&main_arena.mutex);
main_arena.next = &main_arena;
@@ -363,8 +425,13 @@ ptmalloc_init __MALLOC_P((void))
tsd_setspecific(arena_key, (Void_t *)&main_arena);
thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2);
#ifndef NO_THREADS
+# ifndef NO_STARTER
__malloc_hook = save_malloc_hook;
+ __memalign_hook = save_memalign_hook;
__free_hook = save_free_hook;
+# else
+# undef NO_STARTER
+# endif
#endif
#ifdef _LIBC
secure = __libc_enable_secure;
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 7643e36..0bd3e2a 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -395,6 +395,17 @@ memalign_check(alignment, bytes, caller)
#ifndef NO_THREADS
+# ifdef _LIBC
+# if USE___THREAD || (defined USE_TLS && !defined SHARED)
+ /* These routines are never needed in this configuration. */
+# define NO_STARTER
+# endif
+# endif
+
+# ifdef NO_STARTER
+# undef NO_STARTER
+# else
+
/* The following hooks are used when the global initialization in
ptmalloc_init() hasn't completed yet. */
@@ -412,6 +423,20 @@ malloc_starter(sz, caller) size_t sz; const Void_t *caller;
return victim ? BOUNDED_N(victim, sz) : 0;
}
+static Void_t*
+#if __STD_C
+memalign_starter(size_t align, size_t sz, const Void_t *caller)
+#else
+memalign_starter(align, sz, caller) size_t align, sz; const Void_t *caller;
+#endif
+{
+ Void_t* victim;
+
+ victim = _int_memalign(&main_arena, align, sz);
+
+ return victim ? BOUNDED_N(victim, sz) : 0;
+}
+
static void
#if __STD_C
free_starter(Void_t* mem, const Void_t *caller)
@@ -432,6 +457,7 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller;
_int_free(&main_arena, mem);
}
+# endif /* !defiend NO_STARTER */
#endif /* NO_THREADS */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 757e65a..36a244d 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1498,8 +1498,19 @@ static Void_t* realloc_check(Void_t* oldmem, size_t bytes,
static Void_t* memalign_check(size_t alignment, size_t bytes,
const Void_t *caller);
#ifndef NO_THREADS
+# ifdef _LIBC
+# if USE___THREAD || (defined USE_TLS && !defined SHARED)
+ /* These routines are never needed in this configuration. */
+# define NO_STARTER
+# endif
+# endif
+# ifdef NO_STARTER
+# undef NO_STARTER
+# else
static Void_t* malloc_starter(size_t sz, const Void_t *caller);
+static Void_t* memalign_starter(size_t aln, size_t sz, const Void_t *caller);
static void free_starter(Void_t* mem, const Void_t *caller);
+# endif
static Void_t* malloc_atfork(size_t sz, const Void_t *caller);
static void free_atfork(Void_t* mem, const Void_t *caller);
#endif