xref: /aosp_15_r20/external/musl/src/malloc/mallocng/mallinfo.c (revision c9945492fdd68bbe62686c5b452b4dc1be3f8453)
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)8 static 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)45 static 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)54 struct 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)71 struct 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