xref: /aosp_15_r20/external/jemalloc_new/test/integration/rallocx.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker 
3*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nsizes_impl(const char * cmd)4*1208bc7eSAndroid Build Coastguard Worker get_nsizes_impl(const char *cmd) {
5*1208bc7eSAndroid Build Coastguard Worker 	unsigned ret;
6*1208bc7eSAndroid Build Coastguard Worker 	size_t z;
7*1208bc7eSAndroid Build Coastguard Worker 
8*1208bc7eSAndroid Build Coastguard Worker 	z = sizeof(unsigned);
9*1208bc7eSAndroid Build Coastguard Worker 	assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
10*1208bc7eSAndroid Build Coastguard Worker 	    "Unexpected mallctl(\"%s\", ...) failure", cmd);
11*1208bc7eSAndroid Build Coastguard Worker 
12*1208bc7eSAndroid Build Coastguard Worker 	return ret;
13*1208bc7eSAndroid Build Coastguard Worker }
14*1208bc7eSAndroid Build Coastguard Worker 
15*1208bc7eSAndroid Build Coastguard Worker static unsigned
get_nlarge(void)16*1208bc7eSAndroid Build Coastguard Worker get_nlarge(void) {
17*1208bc7eSAndroid Build Coastguard Worker 	return get_nsizes_impl("arenas.nlextents");
18*1208bc7eSAndroid Build Coastguard Worker }
19*1208bc7eSAndroid Build Coastguard Worker 
20*1208bc7eSAndroid Build Coastguard Worker static size_t
get_size_impl(const char * cmd,size_t ind)21*1208bc7eSAndroid Build Coastguard Worker get_size_impl(const char *cmd, size_t ind) {
22*1208bc7eSAndroid Build Coastguard Worker 	size_t ret;
23*1208bc7eSAndroid Build Coastguard Worker 	size_t z;
24*1208bc7eSAndroid Build Coastguard Worker 	size_t mib[4];
25*1208bc7eSAndroid Build Coastguard Worker 	size_t miblen = 4;
26*1208bc7eSAndroid Build Coastguard Worker 
27*1208bc7eSAndroid Build Coastguard Worker 	z = sizeof(size_t);
28*1208bc7eSAndroid Build Coastguard Worker 	assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
29*1208bc7eSAndroid Build Coastguard Worker 	    0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
30*1208bc7eSAndroid Build Coastguard Worker 	mib[2] = ind;
31*1208bc7eSAndroid Build Coastguard Worker 	z = sizeof(size_t);
32*1208bc7eSAndroid Build Coastguard Worker 	assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
33*1208bc7eSAndroid Build Coastguard Worker 	    0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
34*1208bc7eSAndroid Build Coastguard Worker 
35*1208bc7eSAndroid Build Coastguard Worker 	return ret;
36*1208bc7eSAndroid Build Coastguard Worker }
37*1208bc7eSAndroid Build Coastguard Worker 
38*1208bc7eSAndroid Build Coastguard Worker static size_t
get_large_size(size_t ind)39*1208bc7eSAndroid Build Coastguard Worker get_large_size(size_t ind) {
40*1208bc7eSAndroid Build Coastguard Worker 	return get_size_impl("arenas.lextent.0.size", ind);
41*1208bc7eSAndroid Build Coastguard Worker }
42*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_grow_and_shrink)43*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_grow_and_shrink) {
44*1208bc7eSAndroid Build Coastguard Worker 	void *p, *q;
45*1208bc7eSAndroid Build Coastguard Worker 	size_t tsz;
46*1208bc7eSAndroid Build Coastguard Worker #define NCYCLES 3
47*1208bc7eSAndroid Build Coastguard Worker 	unsigned i, j;
48*1208bc7eSAndroid Build Coastguard Worker #define NSZS 1024
49*1208bc7eSAndroid Build Coastguard Worker 	size_t szs[NSZS];
50*1208bc7eSAndroid Build Coastguard Worker #define MAXSZ ZU(12 * 1024 * 1024)
51*1208bc7eSAndroid Build Coastguard Worker 
52*1208bc7eSAndroid Build Coastguard Worker 	p = mallocx(1, 0);
53*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_not_null(p, "Unexpected mallocx() error");
54*1208bc7eSAndroid Build Coastguard Worker 	szs[0] = sallocx(p, 0);
55*1208bc7eSAndroid Build Coastguard Worker 
56*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < NCYCLES; i++) {
57*1208bc7eSAndroid Build Coastguard Worker 		for (j = 1; j < NSZS && szs[j-1] < MAXSZ; j++) {
58*1208bc7eSAndroid Build Coastguard Worker 			q = rallocx(p, szs[j-1]+1, 0);
59*1208bc7eSAndroid Build Coastguard Worker 			assert_ptr_not_null(q,
60*1208bc7eSAndroid Build Coastguard Worker 			    "Unexpected rallocx() error for size=%zu-->%zu",
61*1208bc7eSAndroid Build Coastguard Worker 			    szs[j-1], szs[j-1]+1);
62*1208bc7eSAndroid Build Coastguard Worker 			szs[j] = sallocx(q, 0);
63*1208bc7eSAndroid Build Coastguard Worker 			assert_zu_ne(szs[j], szs[j-1]+1,
64*1208bc7eSAndroid Build Coastguard Worker 			    "Expected size to be at least: %zu", szs[j-1]+1);
65*1208bc7eSAndroid Build Coastguard Worker 			p = q;
66*1208bc7eSAndroid Build Coastguard Worker 		}
67*1208bc7eSAndroid Build Coastguard Worker 
68*1208bc7eSAndroid Build Coastguard Worker 		for (j--; j > 0; j--) {
69*1208bc7eSAndroid Build Coastguard Worker 			q = rallocx(p, szs[j-1], 0);
70*1208bc7eSAndroid Build Coastguard Worker 			assert_ptr_not_null(q,
71*1208bc7eSAndroid Build Coastguard Worker 			    "Unexpected rallocx() error for size=%zu-->%zu",
72*1208bc7eSAndroid Build Coastguard Worker 			    szs[j], szs[j-1]);
73*1208bc7eSAndroid Build Coastguard Worker 			tsz = sallocx(q, 0);
74*1208bc7eSAndroid Build Coastguard Worker 			assert_zu_eq(tsz, szs[j-1],
75*1208bc7eSAndroid Build Coastguard Worker 			    "Expected size=%zu, got size=%zu", szs[j-1], tsz);
76*1208bc7eSAndroid Build Coastguard Worker 			p = q;
77*1208bc7eSAndroid Build Coastguard Worker 		}
78*1208bc7eSAndroid Build Coastguard Worker 	}
79*1208bc7eSAndroid Build Coastguard Worker 
80*1208bc7eSAndroid Build Coastguard Worker 	dallocx(p, 0);
81*1208bc7eSAndroid Build Coastguard Worker #undef MAXSZ
82*1208bc7eSAndroid Build Coastguard Worker #undef NSZS
83*1208bc7eSAndroid Build Coastguard Worker #undef NCYCLES
84*1208bc7eSAndroid Build Coastguard Worker }
85*1208bc7eSAndroid Build Coastguard Worker TEST_END
86*1208bc7eSAndroid Build Coastguard Worker 
87*1208bc7eSAndroid Build Coastguard Worker static bool
validate_fill(const void * p,uint8_t c,size_t offset,size_t len)88*1208bc7eSAndroid Build Coastguard Worker validate_fill(const void *p, uint8_t c, size_t offset, size_t len) {
89*1208bc7eSAndroid Build Coastguard Worker 	bool ret = false;
90*1208bc7eSAndroid Build Coastguard Worker 	const uint8_t *buf = (const uint8_t *)p;
91*1208bc7eSAndroid Build Coastguard Worker 	size_t i;
92*1208bc7eSAndroid Build Coastguard Worker 
93*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
94*1208bc7eSAndroid Build Coastguard Worker 		uint8_t b = buf[offset+i];
95*1208bc7eSAndroid Build Coastguard Worker 		if (b != c) {
96*1208bc7eSAndroid Build Coastguard Worker 			test_fail("Allocation at %p (len=%zu) contains %#x "
97*1208bc7eSAndroid Build Coastguard Worker 			    "rather than %#x at offset %zu", p, len, b, c,
98*1208bc7eSAndroid Build Coastguard Worker 			    offset+i);
99*1208bc7eSAndroid Build Coastguard Worker 			ret = true;
100*1208bc7eSAndroid Build Coastguard Worker 		}
101*1208bc7eSAndroid Build Coastguard Worker 	}
102*1208bc7eSAndroid Build Coastguard Worker 
103*1208bc7eSAndroid Build Coastguard Worker 	return ret;
104*1208bc7eSAndroid Build Coastguard Worker }
105*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_zero)106*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_zero) {
107*1208bc7eSAndroid Build Coastguard Worker 	void *p, *q;
108*1208bc7eSAndroid Build Coastguard Worker 	size_t psz, qsz, i, j;
109*1208bc7eSAndroid Build Coastguard Worker 	size_t start_sizes[] = {1, 3*1024, 63*1024, 4095*1024};
110*1208bc7eSAndroid Build Coastguard Worker #define FILL_BYTE 0xaaU
111*1208bc7eSAndroid Build Coastguard Worker #define RANGE 2048
112*1208bc7eSAndroid Build Coastguard Worker 
113*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < sizeof(start_sizes)/sizeof(size_t); i++) {
114*1208bc7eSAndroid Build Coastguard Worker 		size_t start_size = start_sizes[i];
115*1208bc7eSAndroid Build Coastguard Worker 		p = mallocx(start_size, MALLOCX_ZERO);
116*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_not_null(p, "Unexpected mallocx() error");
117*1208bc7eSAndroid Build Coastguard Worker 		psz = sallocx(p, 0);
118*1208bc7eSAndroid Build Coastguard Worker 
119*1208bc7eSAndroid Build Coastguard Worker 		assert_false(validate_fill(p, 0, 0, psz),
120*1208bc7eSAndroid Build Coastguard Worker 		    "Expected zeroed memory");
121*1208bc7eSAndroid Build Coastguard Worker 		memset(p, FILL_BYTE, psz);
122*1208bc7eSAndroid Build Coastguard Worker 		assert_false(validate_fill(p, FILL_BYTE, 0, psz),
123*1208bc7eSAndroid Build Coastguard Worker 		    "Expected filled memory");
124*1208bc7eSAndroid Build Coastguard Worker 
125*1208bc7eSAndroid Build Coastguard Worker 		for (j = 1; j < RANGE; j++) {
126*1208bc7eSAndroid Build Coastguard Worker 			q = rallocx(p, start_size+j, MALLOCX_ZERO);
127*1208bc7eSAndroid Build Coastguard Worker 			assert_ptr_not_null(q, "Unexpected rallocx() error");
128*1208bc7eSAndroid Build Coastguard Worker 			qsz = sallocx(q, 0);
129*1208bc7eSAndroid Build Coastguard Worker 			if (q != p || qsz != psz) {
130*1208bc7eSAndroid Build Coastguard Worker 				assert_false(validate_fill(q, FILL_BYTE, 0,
131*1208bc7eSAndroid Build Coastguard Worker 				    psz), "Expected filled memory");
132*1208bc7eSAndroid Build Coastguard Worker 				assert_false(validate_fill(q, 0, psz, qsz-psz),
133*1208bc7eSAndroid Build Coastguard Worker 				    "Expected zeroed memory");
134*1208bc7eSAndroid Build Coastguard Worker 			}
135*1208bc7eSAndroid Build Coastguard Worker 			if (psz != qsz) {
136*1208bc7eSAndroid Build Coastguard Worker 				memset((void *)((uintptr_t)q+psz), FILL_BYTE,
137*1208bc7eSAndroid Build Coastguard Worker 				    qsz-psz);
138*1208bc7eSAndroid Build Coastguard Worker 				psz = qsz;
139*1208bc7eSAndroid Build Coastguard Worker 			}
140*1208bc7eSAndroid Build Coastguard Worker 			p = q;
141*1208bc7eSAndroid Build Coastguard Worker 		}
142*1208bc7eSAndroid Build Coastguard Worker 		assert_false(validate_fill(p, FILL_BYTE, 0, psz),
143*1208bc7eSAndroid Build Coastguard Worker 		    "Expected filled memory");
144*1208bc7eSAndroid Build Coastguard Worker 		dallocx(p, 0);
145*1208bc7eSAndroid Build Coastguard Worker 	}
146*1208bc7eSAndroid Build Coastguard Worker #undef FILL_BYTE
147*1208bc7eSAndroid Build Coastguard Worker }
148*1208bc7eSAndroid Build Coastguard Worker TEST_END
149*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_align)150*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_align) {
151*1208bc7eSAndroid Build Coastguard Worker 	void *p, *q;
152*1208bc7eSAndroid Build Coastguard Worker 	size_t align;
153*1208bc7eSAndroid Build Coastguard Worker #define MAX_ALIGN (ZU(1) << 25)
154*1208bc7eSAndroid Build Coastguard Worker 
155*1208bc7eSAndroid Build Coastguard Worker 	align = ZU(1);
156*1208bc7eSAndroid Build Coastguard Worker 	p = mallocx(1, MALLOCX_ALIGN(align));
157*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_not_null(p, "Unexpected mallocx() error");
158*1208bc7eSAndroid Build Coastguard Worker 
159*1208bc7eSAndroid Build Coastguard Worker 	for (align <<= 1; align <= MAX_ALIGN; align <<= 1) {
160*1208bc7eSAndroid Build Coastguard Worker 		q = rallocx(p, 1, MALLOCX_ALIGN(align));
161*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_not_null(q,
162*1208bc7eSAndroid Build Coastguard Worker 		    "Unexpected rallocx() error for align=%zu", align);
163*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_null(
164*1208bc7eSAndroid Build Coastguard Worker 		    (void *)((uintptr_t)q & (align-1)),
165*1208bc7eSAndroid Build Coastguard Worker 		    "%p inadequately aligned for align=%zu",
166*1208bc7eSAndroid Build Coastguard Worker 		    q, align);
167*1208bc7eSAndroid Build Coastguard Worker 		p = q;
168*1208bc7eSAndroid Build Coastguard Worker 	}
169*1208bc7eSAndroid Build Coastguard Worker 	dallocx(p, 0);
170*1208bc7eSAndroid Build Coastguard Worker #undef MAX_ALIGN
171*1208bc7eSAndroid Build Coastguard Worker }
172*1208bc7eSAndroid Build Coastguard Worker TEST_END
173*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_lg_align_and_zero)174*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_lg_align_and_zero) {
175*1208bc7eSAndroid Build Coastguard Worker 	void *p, *q;
176*1208bc7eSAndroid Build Coastguard Worker 	unsigned lg_align;
177*1208bc7eSAndroid Build Coastguard Worker 	size_t sz;
178*1208bc7eSAndroid Build Coastguard Worker #define MAX_LG_ALIGN 25
179*1208bc7eSAndroid Build Coastguard Worker #define MAX_VALIDATE (ZU(1) << 22)
180*1208bc7eSAndroid Build Coastguard Worker 
181*1208bc7eSAndroid Build Coastguard Worker 	lg_align = 0;
182*1208bc7eSAndroid Build Coastguard Worker 	p = mallocx(1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
183*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_not_null(p, "Unexpected mallocx() error");
184*1208bc7eSAndroid Build Coastguard Worker 
185*1208bc7eSAndroid Build Coastguard Worker 	for (lg_align++; lg_align <= MAX_LG_ALIGN; lg_align++) {
186*1208bc7eSAndroid Build Coastguard Worker 		q = rallocx(p, 1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO);
187*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_not_null(q,
188*1208bc7eSAndroid Build Coastguard Worker 		    "Unexpected rallocx() error for lg_align=%u", lg_align);
189*1208bc7eSAndroid Build Coastguard Worker 		assert_ptr_null(
190*1208bc7eSAndroid Build Coastguard Worker 		    (void *)((uintptr_t)q & ((ZU(1) << lg_align)-1)),
191*1208bc7eSAndroid Build Coastguard Worker 		    "%p inadequately aligned for lg_align=%u", q, lg_align);
192*1208bc7eSAndroid Build Coastguard Worker 		sz = sallocx(q, 0);
193*1208bc7eSAndroid Build Coastguard Worker 		if ((sz << 1) <= MAX_VALIDATE) {
194*1208bc7eSAndroid Build Coastguard Worker 			assert_false(validate_fill(q, 0, 0, sz),
195*1208bc7eSAndroid Build Coastguard Worker 			    "Expected zeroed memory");
196*1208bc7eSAndroid Build Coastguard Worker 		} else {
197*1208bc7eSAndroid Build Coastguard Worker 			assert_false(validate_fill(q, 0, 0, MAX_VALIDATE),
198*1208bc7eSAndroid Build Coastguard Worker 			    "Expected zeroed memory");
199*1208bc7eSAndroid Build Coastguard Worker 			assert_false(validate_fill(
200*1208bc7eSAndroid Build Coastguard Worker 			    (void *)((uintptr_t)q+sz-MAX_VALIDATE),
201*1208bc7eSAndroid Build Coastguard Worker 			    0, 0, MAX_VALIDATE), "Expected zeroed memory");
202*1208bc7eSAndroid Build Coastguard Worker 		}
203*1208bc7eSAndroid Build Coastguard Worker 		p = q;
204*1208bc7eSAndroid Build Coastguard Worker 	}
205*1208bc7eSAndroid Build Coastguard Worker 	dallocx(p, 0);
206*1208bc7eSAndroid Build Coastguard Worker #undef MAX_VALIDATE
207*1208bc7eSAndroid Build Coastguard Worker #undef MAX_LG_ALIGN
208*1208bc7eSAndroid Build Coastguard Worker }
209*1208bc7eSAndroid Build Coastguard Worker TEST_END
210*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_overflow)211*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_overflow) {
212*1208bc7eSAndroid Build Coastguard Worker 	size_t largemax;
213*1208bc7eSAndroid Build Coastguard Worker 	void *p;
214*1208bc7eSAndroid Build Coastguard Worker 
215*1208bc7eSAndroid Build Coastguard Worker 	largemax = get_large_size(get_nlarge()-1);
216*1208bc7eSAndroid Build Coastguard Worker 
217*1208bc7eSAndroid Build Coastguard Worker 	p = mallocx(1, 0);
218*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
219*1208bc7eSAndroid Build Coastguard Worker 
220*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(rallocx(p, largemax+1, 0),
221*1208bc7eSAndroid Build Coastguard Worker 	    "Expected OOM for rallocx(p, size=%#zx, 0)", largemax+1);
222*1208bc7eSAndroid Build Coastguard Worker 
223*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(rallocx(p, ZU(PTRDIFF_MAX)+1, 0),
224*1208bc7eSAndroid Build Coastguard Worker 	    "Expected OOM for rallocx(p, size=%#zx, 0)", ZU(PTRDIFF_MAX)+1);
225*1208bc7eSAndroid Build Coastguard Worker 
226*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(rallocx(p, SIZE_T_MAX, 0),
227*1208bc7eSAndroid Build Coastguard Worker 	    "Expected OOM for rallocx(p, size=%#zx, 0)", SIZE_T_MAX);
228*1208bc7eSAndroid Build Coastguard Worker 
229*1208bc7eSAndroid Build Coastguard Worker 	assert_ptr_null(rallocx(p, 1, MALLOCX_ALIGN(ZU(PTRDIFF_MAX)+1)),
230*1208bc7eSAndroid Build Coastguard Worker 	    "Expected OOM for rallocx(p, size=1, MALLOCX_ALIGN(%#zx))",
231*1208bc7eSAndroid Build Coastguard Worker 	    ZU(PTRDIFF_MAX)+1);
232*1208bc7eSAndroid Build Coastguard Worker 
233*1208bc7eSAndroid Build Coastguard Worker 	dallocx(p, 0);
234*1208bc7eSAndroid Build Coastguard Worker }
235*1208bc7eSAndroid Build Coastguard Worker TEST_END
236*1208bc7eSAndroid Build Coastguard Worker 
237*1208bc7eSAndroid Build Coastguard Worker int
main(void)238*1208bc7eSAndroid Build Coastguard Worker main(void) {
239*1208bc7eSAndroid Build Coastguard Worker 	return test(
240*1208bc7eSAndroid Build Coastguard Worker 	    test_grow_and_shrink,
241*1208bc7eSAndroid Build Coastguard Worker 	    test_zero,
242*1208bc7eSAndroid Build Coastguard Worker 	    test_align,
243*1208bc7eSAndroid Build Coastguard Worker 	    test_lg_align_and_zero,
244*1208bc7eSAndroid Build Coastguard Worker 	    test_overflow);
245*1208bc7eSAndroid Build Coastguard Worker }
246