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