[PATCH v3] malloc: Improve malloc initialization
Wilco Dijkstra
Wilco.Dijkstra@arm.com
Fri May 2 12:16:27 GMT 2025
Move malloc initialization to __libc_early_init. Use a hidden __ptmalloc_init
for initialization and a weak call to avoid pulling in the system malloc in a
static binary. All previous initialization checks can now be removed.
Passes regress, OK for commit?
---
diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c
index 07202317534a4edbd2202c6e45770094cadb67f6..24b99d82fe28f4c324800dbc665fb0e9c702c228 100644
--- a/elf/libc_early_init.c
+++ b/elf/libc_early_init.c
@@ -24,6 +24,7 @@
#include <pthread_early_init.h>
#include <sys/single_threaded.h>
#include <getrandom-internal.h>
+#include <malloc/malloc-internal.h>
#ifdef SHARED
_Bool __libc_initial;
@@ -32,6 +33,9 @@ _Bool __libc_initial;
void
__libc_early_init (_Bool initial)
{
+ /* Initialize system malloc. */
+ call_function_static_weak (__ptmalloc_init);
+
/* Initialize ctype data. */
__ctype_init ();
diff --git a/malloc/arena.c b/malloc/arena.c
index 5672c699aa1a0306a13ebc54a08263f35024b3f1..48786de1b32b8b61b4d928297611a45e2d7d90e8 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -259,8 +259,8 @@ TUNABLE_CALLBACK_FNDECL (set_hugetlb, size_t)
static void tcache_key_initialize (void);
#endif
-static void
-ptmalloc_init (void)
+void
+__ptmalloc_init (void)
{
if (__malloc_initialized)
return;
diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
index c5265ecb91f1ae6eba9589f134158abba1126917..fbb030116c3cc7e0b3a577822f11467d97c82b8d 100644
--- a/malloc/malloc-check.c
+++ b/malloc/malloc-check.c
@@ -389,7 +389,7 @@ initialize_malloc_check (void)
{
/* This is the copy of the malloc initializer that we pulled in along with
malloc-check. This does not affect any of the libc malloc structures. */
- ptmalloc_init ();
+ __ptmalloc_init ();
TUNABLE_GET (check, int32_t, TUNABLE_CALLBACK (set_mallopt_check));
return __is_malloc_debug_enabled (MALLOC_CHECK_HOOK);
}
diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h
index d88ed20c4622f9e03de6a26b4d8a3bb6fff7a83e..0f1b3a1d5d54a75d8289b5f7ff78c6985f751941 100644
--- a/malloc/malloc-internal.h
+++ b/malloc/malloc-internal.h
@@ -40,4 +40,7 @@ void __malloc_arena_thread_freeres (void) attribute_hidden;
/* Activate a standard set of debugging hooks. */
void __malloc_check_init (void) attribute_hidden;
+/* Initialize malloc. */
+void __ptmalloc_init (void) attribute_hidden;
+
#endif /* _MALLOC_INTERNAL_H */
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 9d860eac9cc923ef8f20218eb37f35b926f3ef82..acf0075acf3173d897229bfd2ea17bbcbc60ec97 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1937,7 +1937,7 @@ static struct malloc_par mp_ =
/*
Initialize a malloc_state struct.
- This is called from ptmalloc_init () or from _int_new_arena ()
+ This is called from __ptmalloc_init () or from _int_new_arena ()
when creating a new arena.
*/
@@ -3344,9 +3344,6 @@ __libc_malloc2 (size_t bytes)
mstate ar_ptr;
void *victim;
- if (!__malloc_initialized)
- ptmalloc_init ();
-
MAYBE_INIT_TCACHE ();
if (SINGLE_THREAD_P)
@@ -3452,9 +3449,6 @@ __libc_realloc (void *oldmem, size_t bytes)
void *newp; /* chunk to return */
- if (!__malloc_initialized)
- ptmalloc_init ();
-
#if REALLOC_ZERO_BYTES_FREES
if (bytes == 0 && oldmem != NULL)
{
@@ -3580,9 +3574,6 @@ libc_hidden_def (__libc_realloc)
void *
__libc_memalign (size_t alignment, size_t bytes)
{
- if (!__malloc_initialized)
- ptmalloc_init ();
-
void *address = RETURN_ADDRESS (0);
return _mid_memalign (alignment, bytes, address);
}
@@ -3593,9 +3584,6 @@ void *
weak_function
aligned_alloc (size_t alignment, size_t bytes)
{
- if (!__malloc_initialized)
- ptmalloc_init ();
-
/* Similar to memalign, but starting with ISO C17 the standard
requires an error for alignments that are not supported by the
implementation. Valid alignments for the current implementation
@@ -3695,9 +3683,6 @@ _mid_memalign (size_t alignment, size_t bytes, void *address)
void *
__libc_valloc (size_t bytes)
{
- if (!__malloc_initialized)
- ptmalloc_init ();
-
void *address = RETURN_ADDRESS (0);
size_t pagesize = GLRO (dl_pagesize);
return _mid_memalign (pagesize, bytes, address);
@@ -3706,9 +3691,6 @@ __libc_valloc (size_t bytes)
void *
__libc_pvalloc (size_t bytes)
{
- if (!__malloc_initialized)
- ptmalloc_init ();
-
void *address = RETURN_ADDRESS (0);
size_t pagesize = GLRO (dl_pagesize);
size_t rounded_bytes;
@@ -3743,9 +3725,6 @@ __libc_calloc (size_t n, size_t elem_size)
sz = bytes;
- if (!__malloc_initialized)
- ptmalloc_init ();
-
#if USE_TCACHE
size_t tc_idx = usize2tidx (bytes);
if (tcache_available (tc_idx))
@@ -5208,9 +5187,6 @@ __malloc_trim (size_t s)
{
int result = 0;
- if (!__malloc_initialized)
- ptmalloc_init ();
-
mstate ar_ptr = &main_arena;
do
{
@@ -5327,9 +5303,6 @@ __libc_mallinfo2 (void)
struct mallinfo2 m;
mstate ar_ptr;
- if (!__malloc_initialized)
- ptmalloc_init ();
-
memset (&m, 0, sizeof (m));
ar_ptr = &main_arena;
do
@@ -5378,8 +5351,6 @@ __malloc_stats (void)
mstate ar_ptr;
unsigned int in_use_b = mp_.mmapped_mem, system_b = in_use_b;
- if (!__malloc_initialized)
- ptmalloc_init ();
_IO_flockfile (stderr);
int old_flags2 = stderr->_flags2;
stderr->_flags2 |= _IO_FLAGS2_NOTCANCEL;
@@ -5560,8 +5531,6 @@ __libc_mallopt (int param_number, int value)
mstate av = &main_arena;
int res = 1;
- if (!__malloc_initialized)
- ptmalloc_init ();
__libc_lock_lock (av->mutex);
LIBC_PROBE (memory_mallopt, 2, param_number, value);
@@ -5794,9 +5763,6 @@ __posix_memalign (void **memptr, size_t alignment, size_t size)
{
void *mem;
- if (!__malloc_initialized)
- ptmalloc_init ();
-
/* Test whether the SIZE argument is valid. It must be a power of
two multiple of sizeof (void *). */
if (alignment % sizeof (void *) != 0
@@ -5837,11 +5803,6 @@ __malloc_info (int options, FILE *fp)
size_t total_aspace = 0;
size_t total_aspace_mprotect = 0;
-
-
- if (!__malloc_initialized)
- ptmalloc_init ();
-
fputs ("<malloc version=\"1\">\n", fp);
/* Iterate over all arenas currently in use. */
More information about the Libc-alpha
mailing list