1*c9945492SAndroid Build Coastguard Worker #include <limits.h> 2*c9945492SAndroid Build Coastguard Worker #include <malloc.h> 3*c9945492SAndroid Build Coastguard Worker #include <stddef.h> 4*c9945492SAndroid Build Coastguard Worker 5*c9945492SAndroid Build Coastguard Worker #include "glue.h" 6*c9945492SAndroid Build Coastguard Worker #include "meta.h" 7*c9945492SAndroid Build Coastguard Worker accumulate_meta(struct mallinfo2 * mi,struct meta * g)8*c9945492SAndroid Build Coastguard Workerstatic void accumulate_meta(struct mallinfo2 *mi, struct meta *g) 9*c9945492SAndroid Build Coastguard Worker { 10*c9945492SAndroid Build Coastguard Worker int sc = g->sizeclass; 11*c9945492SAndroid Build Coastguard Worker if (sc >= 48) { 12*c9945492SAndroid Build Coastguard Worker // Large mmap allocation 13*c9945492SAndroid Build Coastguard Worker mi->hblks++; 14*c9945492SAndroid Build Coastguard Worker mi->uordblks += g->maplen*4096; 15*c9945492SAndroid Build Coastguard Worker mi->hblkhd += g->maplen*4096; 16*c9945492SAndroid Build Coastguard Worker } else { 17*c9945492SAndroid Build Coastguard Worker if (g->freeable && !g->maplen) { 18*c9945492SAndroid Build Coastguard Worker // Small size slots are embedded in a larger slot, avoid 19*c9945492SAndroid Build Coastguard Worker // double counting by subtracting the size of the larger 20*c9945492SAndroid Build Coastguard Worker // slot from the total used memory. 21*c9945492SAndroid Build Coastguard Worker struct meta* outer_g = get_meta((void*)g->mem); 22*c9945492SAndroid Build Coastguard Worker int outer_sc = outer_g->sizeclass; 23*c9945492SAndroid Build Coastguard Worker int outer_sz = size_classes[outer_sc]*UNIT; 24*c9945492SAndroid Build Coastguard Worker mi->uordblks -= outer_sz; 25*c9945492SAndroid Build Coastguard Worker mi->arena -= outer_sz; 26*c9945492SAndroid Build Coastguard Worker } 27*c9945492SAndroid Build Coastguard Worker int sz = size_classes[sc]*UNIT; 28*c9945492SAndroid Build Coastguard Worker int mask = g->avail_mask | g->freed_mask; 29*c9945492SAndroid Build Coastguard Worker int nr_unused = a_popcount_32(mask); 30*c9945492SAndroid Build Coastguard Worker 31*c9945492SAndroid Build Coastguard Worker if (!g->last_idx) { 32*c9945492SAndroid Build Coastguard Worker // Allocation groups with a single allocation may use a 33*c9945492SAndroid Build Coastguard Worker // smaller maplen than normally used for the size class. 34*c9945492SAndroid Build Coastguard Worker if (sz > g->maplen-IB-UNIT) { 35*c9945492SAndroid Build Coastguard Worker sz = g->maplen-IB-UNIT; 36*c9945492SAndroid Build Coastguard Worker } 37*c9945492SAndroid Build Coastguard Worker } 38*c9945492SAndroid Build Coastguard Worker mi->arena += sz*(g->last_idx+1); 39*c9945492SAndroid Build Coastguard Worker mi->ordblks += nr_unused; 40*c9945492SAndroid Build Coastguard Worker mi->uordblks += sz*(g->last_idx+1-nr_unused); 41*c9945492SAndroid Build Coastguard Worker mi->fordblks += sz*nr_unused; 42*c9945492SAndroid Build Coastguard Worker } 43*c9945492SAndroid Build Coastguard Worker } 44*c9945492SAndroid Build Coastguard Worker accumulate_meta_area(struct mallinfo2 * mi,struct meta_area * ma)45*c9945492SAndroid Build Coastguard Workerstatic void accumulate_meta_area(struct mallinfo2 *mi, struct meta_area *ma) 46*c9945492SAndroid Build Coastguard Worker { 47*c9945492SAndroid Build Coastguard Worker for (int i=0; i<ma->nslots; i++) { 48*c9945492SAndroid Build Coastguard Worker if (ma->slots[i].mem) { 49*c9945492SAndroid Build Coastguard Worker accumulate_meta(mi, &ma->slots[i]); 50*c9945492SAndroid Build Coastguard Worker } 51*c9945492SAndroid Build Coastguard Worker } 52*c9945492SAndroid Build Coastguard Worker } 53*c9945492SAndroid Build Coastguard Worker mallinfo2(void)54*c9945492SAndroid Build Coastguard Workerstruct mallinfo2 mallinfo2(void) 55*c9945492SAndroid Build Coastguard Worker { 56*c9945492SAndroid Build Coastguard Worker struct mallinfo2 mi = {0}; 57*c9945492SAndroid Build Coastguard Worker 58*c9945492SAndroid Build Coastguard Worker rdlock(); 59*c9945492SAndroid Build Coastguard Worker struct meta_area *ma = ctx.meta_area_head; 60*c9945492SAndroid Build Coastguard Worker while (ma) { 61*c9945492SAndroid Build Coastguard Worker accumulate_meta_area(&mi, ma); 62*c9945492SAndroid Build Coastguard Worker ma = ma->next; 63*c9945492SAndroid Build Coastguard Worker } 64*c9945492SAndroid Build Coastguard Worker unlock(); 65*c9945492SAndroid Build Coastguard Worker 66*c9945492SAndroid Build Coastguard Worker return mi; 67*c9945492SAndroid Build Coastguard Worker } 68*c9945492SAndroid Build Coastguard Worker 69*c9945492SAndroid Build Coastguard Worker #define cap(x) ((x > INT_MAX) ? INT_MAX : x) 70*c9945492SAndroid Build Coastguard Worker mallinfo(void)71*c9945492SAndroid Build Coastguard Workerstruct mallinfo mallinfo(void) { 72*c9945492SAndroid Build Coastguard Worker struct mallinfo mi = {0}; 73*c9945492SAndroid Build Coastguard Worker struct mallinfo2 mi2 = mallinfo2(); 74*c9945492SAndroid Build Coastguard Worker 75*c9945492SAndroid Build Coastguard Worker mi.arena = cap(mi2.arena); 76*c9945492SAndroid Build Coastguard Worker mi.ordblks = cap(mi2.ordblks); 77*c9945492SAndroid Build Coastguard Worker mi.smblks = cap(mi2.smblks); 78*c9945492SAndroid Build Coastguard Worker mi.hblks = cap(mi2.hblks); 79*c9945492SAndroid Build Coastguard Worker mi.hblkhd = cap(mi2.hblkhd); 80*c9945492SAndroid Build Coastguard Worker mi.usmblks = cap(mi2.usmblks); 81*c9945492SAndroid Build Coastguard Worker mi.fsmblks = cap(mi2.fsmblks); 82*c9945492SAndroid Build Coastguard Worker mi.uordblks = cap(mi2.uordblks); 83*c9945492SAndroid Build Coastguard Worker mi.fordblks = cap(mi2.fordblks); 84*c9945492SAndroid Build Coastguard Worker mi.keepcost = cap(mi2.keepcost); 85*c9945492SAndroid Build Coastguard Worker 86*c9945492SAndroid Build Coastguard Worker return mi; 87*c9945492SAndroid Build Coastguard Worker } 88