xref: /aosp_15_r20/external/jemalloc_new/src/android_je_mallinfo.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1*1208bc7eSAndroid Build Coastguard Worker /*
2*1208bc7eSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*1208bc7eSAndroid Build Coastguard Worker  *
4*1208bc7eSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*1208bc7eSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*1208bc7eSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*1208bc7eSAndroid Build Coastguard Worker  *
8*1208bc7eSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*1208bc7eSAndroid Build Coastguard Worker  *
10*1208bc7eSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*1208bc7eSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*1208bc7eSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*1208bc7eSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*1208bc7eSAndroid Build Coastguard Worker  * limitations under the License.
15*1208bc7eSAndroid Build Coastguard Worker  */
16*1208bc7eSAndroid Build Coastguard Worker 
accumulate_large_allocs(arena_t * arena)17*1208bc7eSAndroid Build Coastguard Worker static size_t accumulate_large_allocs(arena_t* arena) {
18*1208bc7eSAndroid Build Coastguard Worker   size_t total_bytes = 0;
19*1208bc7eSAndroid Build Coastguard Worker 
20*1208bc7eSAndroid Build Coastguard Worker   /* Accumulate the large allocation stats.
21*1208bc7eSAndroid Build Coastguard Worker    * Do not include stats.allocated_large, it is only updated by
22*1208bc7eSAndroid Build Coastguard Worker    * arena_stats_merge, and would include the data counted below.
23*1208bc7eSAndroid Build Coastguard Worker    */
24*1208bc7eSAndroid Build Coastguard Worker   for (unsigned j = 0; j < NSIZES - NBINS; j++) {
25*1208bc7eSAndroid Build Coastguard Worker     /* Read ndalloc first so that we guarantee nmalloc >= ndalloc. */
26*1208bc7eSAndroid Build Coastguard Worker     uint64_t ndalloc = arena_stats_read_u64(TSDN_NULL, &arena->stats, &arena->stats.lstats[j].ndalloc);
27*1208bc7eSAndroid Build Coastguard Worker     uint64_t nmalloc = arena_stats_read_u64(TSDN_NULL, &arena->stats, &arena->stats.lstats[j].nmalloc);
28*1208bc7eSAndroid Build Coastguard Worker     size_t allocs = (size_t)(nmalloc - ndalloc);
29*1208bc7eSAndroid Build Coastguard Worker     total_bytes += sz_index2size(NBINS + j) * allocs;
30*1208bc7eSAndroid Build Coastguard Worker   }
31*1208bc7eSAndroid Build Coastguard Worker   return total_bytes;
32*1208bc7eSAndroid Build Coastguard Worker }
33*1208bc7eSAndroid Build Coastguard Worker 
accumulate_small_allocs(arena_t * arena)34*1208bc7eSAndroid Build Coastguard Worker static size_t accumulate_small_allocs(arena_t* arena) {
35*1208bc7eSAndroid Build Coastguard Worker   size_t total_bytes = 0;
36*1208bc7eSAndroid Build Coastguard Worker   for (unsigned j = 0; j < NBINS; j++) {
37*1208bc7eSAndroid Build Coastguard Worker     bin_t* bin = &arena->bins[j];
38*1208bc7eSAndroid Build Coastguard Worker 
39*1208bc7eSAndroid Build Coastguard Worker     /* NOTE: This includes allocations cached on every thread. */
40*1208bc7eSAndroid Build Coastguard Worker     malloc_mutex_lock(TSDN_NULL, &bin->lock);
41*1208bc7eSAndroid Build Coastguard Worker     total_bytes += bin_infos[j].reg_size * bin->stats.curregs;
42*1208bc7eSAndroid Build Coastguard Worker     malloc_mutex_unlock(TSDN_NULL, &bin->lock);
43*1208bc7eSAndroid Build Coastguard Worker   }
44*1208bc7eSAndroid Build Coastguard Worker   return total_bytes;
45*1208bc7eSAndroid Build Coastguard Worker }
46*1208bc7eSAndroid Build Coastguard Worker 
47*1208bc7eSAndroid Build Coastguard Worker 
48*1208bc7eSAndroid Build Coastguard Worker /* Only use bin locks since the stats are now all atomic and can be read
49*1208bc7eSAndroid Build Coastguard Worker  * without taking the stats lock.
50*1208bc7eSAndroid Build Coastguard Worker  */
je_mallinfo()51*1208bc7eSAndroid Build Coastguard Worker struct mallinfo je_mallinfo() {
52*1208bc7eSAndroid Build Coastguard Worker   struct mallinfo mi;
53*1208bc7eSAndroid Build Coastguard Worker   memset(&mi, 0, sizeof(mi));
54*1208bc7eSAndroid Build Coastguard Worker 
55*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_lock(TSDN_NULL, &arenas_lock);
56*1208bc7eSAndroid Build Coastguard Worker   for (unsigned i = 0; i < narenas_auto; i++) {
57*1208bc7eSAndroid Build Coastguard Worker     arena_t* arena = atomic_load_p(&arenas[i], ATOMIC_ACQUIRE);
58*1208bc7eSAndroid Build Coastguard Worker     if (arena != NULL) {
59*1208bc7eSAndroid Build Coastguard Worker       mi.hblkhd += atomic_load_zu(&arena->stats.mapped, ATOMIC_ACQUIRE);
60*1208bc7eSAndroid Build Coastguard Worker 
61*1208bc7eSAndroid Build Coastguard Worker       mi.uordblks += accumulate_small_allocs(arena);
62*1208bc7eSAndroid Build Coastguard Worker       mi.uordblks += accumulate_large_allocs(arena);
63*1208bc7eSAndroid Build Coastguard Worker     }
64*1208bc7eSAndroid Build Coastguard Worker   }
65*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_unlock(TSDN_NULL, &arenas_lock);
66*1208bc7eSAndroid Build Coastguard Worker   mi.fordblks = mi.hblkhd - mi.uordblks;
67*1208bc7eSAndroid Build Coastguard Worker   mi.usmblks = mi.hblkhd;
68*1208bc7eSAndroid Build Coastguard Worker   return mi;
69*1208bc7eSAndroid Build Coastguard Worker }
70*1208bc7eSAndroid Build Coastguard Worker 
je_mallinfo_narenas()71*1208bc7eSAndroid Build Coastguard Worker size_t je_mallinfo_narenas() {
72*1208bc7eSAndroid Build Coastguard Worker   return narenas_auto;
73*1208bc7eSAndroid Build Coastguard Worker }
74*1208bc7eSAndroid Build Coastguard Worker 
je_mallinfo_nbins()75*1208bc7eSAndroid Build Coastguard Worker size_t je_mallinfo_nbins() {
76*1208bc7eSAndroid Build Coastguard Worker   return NBINS;
77*1208bc7eSAndroid Build Coastguard Worker }
78*1208bc7eSAndroid Build Coastguard Worker 
je_mallinfo_arena_info(size_t aidx)79*1208bc7eSAndroid Build Coastguard Worker struct mallinfo je_mallinfo_arena_info(size_t aidx) {
80*1208bc7eSAndroid Build Coastguard Worker   struct mallinfo mi;
81*1208bc7eSAndroid Build Coastguard Worker   memset(&mi, 0, sizeof(mi));
82*1208bc7eSAndroid Build Coastguard Worker 
83*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_lock(TSDN_NULL, &arenas_lock);
84*1208bc7eSAndroid Build Coastguard Worker   if (aidx < narenas_auto) {
85*1208bc7eSAndroid Build Coastguard Worker     arena_t* arena = atomic_load_p(&arenas[aidx], ATOMIC_ACQUIRE);
86*1208bc7eSAndroid Build Coastguard Worker     if (arena != NULL) {
87*1208bc7eSAndroid Build Coastguard Worker       mi.hblkhd = atomic_load_zu(&arena->stats.mapped, ATOMIC_ACQUIRE);
88*1208bc7eSAndroid Build Coastguard Worker       mi.ordblks = accumulate_large_allocs(arena);
89*1208bc7eSAndroid Build Coastguard Worker       mi.fsmblks = accumulate_small_allocs(arena);
90*1208bc7eSAndroid Build Coastguard Worker     }
91*1208bc7eSAndroid Build Coastguard Worker   }
92*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_unlock(TSDN_NULL, &arenas_lock);
93*1208bc7eSAndroid Build Coastguard Worker   return mi;
94*1208bc7eSAndroid Build Coastguard Worker }
95*1208bc7eSAndroid Build Coastguard Worker 
je_mallinfo_bin_info(size_t aidx,size_t bidx)96*1208bc7eSAndroid Build Coastguard Worker struct mallinfo je_mallinfo_bin_info(size_t aidx, size_t bidx) {
97*1208bc7eSAndroid Build Coastguard Worker   struct mallinfo mi;
98*1208bc7eSAndroid Build Coastguard Worker   memset(&mi, 0, sizeof(mi));
99*1208bc7eSAndroid Build Coastguard Worker 
100*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_lock(TSDN_NULL, &arenas_lock);
101*1208bc7eSAndroid Build Coastguard Worker   if (aidx < narenas_auto && bidx < NBINS) {
102*1208bc7eSAndroid Build Coastguard Worker     arena_t* arena = atomic_load_p(&arenas[aidx], ATOMIC_ACQUIRE);
103*1208bc7eSAndroid Build Coastguard Worker     if (arena != NULL) {
104*1208bc7eSAndroid Build Coastguard Worker       bin_t* bin = &arena->bins[bidx];
105*1208bc7eSAndroid Build Coastguard Worker 
106*1208bc7eSAndroid Build Coastguard Worker       malloc_mutex_lock(TSDN_NULL, &bin->lock);
107*1208bc7eSAndroid Build Coastguard Worker       mi.ordblks = bin_infos[bidx].reg_size * bin->stats.curregs;
108*1208bc7eSAndroid Build Coastguard Worker       mi.uordblks = (size_t) bin->stats.nmalloc;
109*1208bc7eSAndroid Build Coastguard Worker       mi.fordblks = (size_t) bin->stats.ndalloc;
110*1208bc7eSAndroid Build Coastguard Worker       malloc_mutex_unlock(TSDN_NULL, &bin->lock);
111*1208bc7eSAndroid Build Coastguard Worker     }
112*1208bc7eSAndroid Build Coastguard Worker   }
113*1208bc7eSAndroid Build Coastguard Worker   malloc_mutex_unlock(TSDN_NULL, &arenas_lock);
114*1208bc7eSAndroid Build Coastguard Worker   return mi;
115*1208bc7eSAndroid Build Coastguard Worker }
116