diff options
Diffstat (limited to 'malloc')
-rw-r--r-- | malloc/arena.c | 81 | ||||
-rw-r--r-- | malloc/hooks.c | 26 | ||||
-rw-r--r-- | malloc/malloc.c | 11 |
3 files changed, 111 insertions, 7 deletions
diff --git a/malloc/arena.c b/malloc/arena.c index 090e3c1dd6..27d2d9e058 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 7643e36714..0bd3e2a9ca 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 757e65a37f..36a244dad7 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 |