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