malloc() を呼び出すのは「 __libc_malloc() 」関数をコールするのと同じことです。
5579 strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc)
この strong_alias は共有ライブラリーのシンボルを指定が可能となっています。
この場合は __libc_malloc のエイリアス(別名)は malloc ということですね。
では __libc_malloc() の中身を確認してみましょう。
malloc.c(https://github.com/MacKomatsu/glibc/blob/release/2.27/master/malloc/malloc.c).
3026 void *
3027 __libc_malloc (size_t bytes)
3028 {
3029 mstate ar_ptr;
3030 void *victim;
3031
3032 void *(*hook) (size_t, const void *)
3033 = atomic_forced_read (__malloc_hook);
3034 if (__builtin_expect (hook != NULL, 0))
3035 return (*hook)(bytes, RETURN_ADDRESS (0));
3036 #if USE_TCACHE
3037 /* int_free also calls request2size, be careful to not pad twice. */
3038 size_t tbytes;
3039 checked_request2size (bytes, tbytes);
3040 size_t tc_idx = csize2tidx (tbytes);
3041
3042 MAYBE_INIT_TCACHE ();
3043
3044 DIAG_PUSH_NEEDS_COMMENT;
3045 if (tc_idx < mp_.tcache_bins
3046 /*&& tc_idx < TCACHE_MAX_BINS*/ /* to appease gcc */
3047 && tcache
3048 && tcache->entries[tc_idx] != NULL)
3049 {
3050 return tcache_get (tc_idx);
3051 }
3052 DIAG_POP_NEEDS_COMMENT;
3053 #endif
3054
3055 if (SINGLE_THREAD_P)
3056 {
3057 victim = _int_malloc (&main_arena, bytes);
3058 assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
3059 &main_arena == arena_for_chunk (mem2chunk (victim)));
3060 return victim;
3061 }
3062
3063 arena_get (ar_ptr, bytes);
3064
3065 victim = _int_malloc (ar_ptr, bytes);
3066 /* Retry with another arena only if we were able to find a usable arena
3067 before. */
3068 if (!victim && ar_ptr != NULL)
3069 {
3070 LIBC_PROBE (memory_malloc_retry, 1, bytes);
3071 ar_ptr = arena_get_retry (ar_ptr, bytes);
3072 victim = _int_malloc (ar_ptr, bytes);
3073 }
3074
3075 if (ar_ptr != NULL)
3076 __libc_lock_unlock (ar_ptr->mutex);
3077
3078 assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
3079 ar_ptr == arena_for_chunk (mem2chunk (victim)));
3080 return victim;
3081 }
3082 libc_hidden_def (__libc_malloc)
シングルスレッドの場合には以下のように _int_malloc() 関数を使い victim に代入したものを返します。
3055 if (SINGLE_THREAD_P)
3056 {
3057 victim = _int_malloc (&main_arena, bytes);
3058 assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
3059 &main_arena == arena_for_chunk (mem2chunk (victim)));
3060 return victim;
3061 }またこの際には main_arena のアドレスをパラメーターとして _int_malloc() 関数に渡しています。
マルチスレッドであれば以下のように適当なアリーナを arena_get() で見つけます。
3063 arena_get (ar_ptr, bytes);
3064
3065 victim = _int_malloc (ar_ptr, bytes);
3066 /* Retry with another arena only if we were able to find a usable arena
3067 before. */
3068 if (!victim && ar_ptr != NULL)
3069 {
3070 LIBC_PROBE (memory_malloc_retry, 1, bytes);
3071 ar_ptr = arena_get_retry (ar_ptr, bytes);
3072 victim = _int_malloc (ar_ptr, bytes);
3073 }
3074
3075 if (ar_ptr != NULL)
3076 __libc_lock_unlock (ar_ptr->mutex);
3077
3078 assert (!victim || chunk_is_mmapped (mem2chunk (victim)) ||
3079 ar_ptr == arena_for_chunk (mem2chunk (victim)));
3080 return victim;基本的には _int_malloc() を使うのはシングルスレッドと一緒ですが、アリーナは main_arena とは限らないです。
Copyright 2018-2019, by Masaki Komatsu