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