xref: /aosp_15_r20/external/jemalloc_new/test/integration/aligned_alloc.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker 
3*1208bc7eSAndroid Build Coastguard Worker #define MAXALIGN (((size_t)1) << 23)
4*1208bc7eSAndroid Build Coastguard Worker 
5*1208bc7eSAndroid Build Coastguard Worker /*
6*1208bc7eSAndroid Build Coastguard Worker  * On systems which can't merge extents, tests that call this function generate
7*1208bc7eSAndroid Build Coastguard Worker  * a lot of dirty memory very quickly.  Purging between cycles mitigates
8*1208bc7eSAndroid Build Coastguard Worker  * potential OOM on e.g. 32-bit Windows.
9*1208bc7eSAndroid Build Coastguard Worker  */
10*1208bc7eSAndroid Build Coastguard Worker static void
purge(void)11*1208bc7eSAndroid Build Coastguard Worker purge(void) {
12*1208bc7eSAndroid Build Coastguard Worker 	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
13*1208bc7eSAndroid Build Coastguard Worker 	    "Unexpected mallctl error");
14*1208bc7eSAndroid Build Coastguard Worker }
15*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_alignment_errors)16*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_alignment_errors) {
17*1208bc7eSAndroid Build Coastguard Worker 	size_t alignment;
18*1208bc7eSAndroid Build Coastguard Worker 	void *p;
19*1208bc7eSAndroid Build Coastguard Worker 
20*1208bc7eSAndroid Build Coastguard Worker 	alignment = 0;
21*1208bc7eSAndroid Build Coastguard Worker 	set_errno(0);
22*1208bc7eSAndroid Build Coastguard Worker 	p = aligned_alloc(alignment, 1);
23*1208bc7eSAndroid Build Coastguard Worker 	assert_false(p != NULL || get_errno() != EINVAL,
24*1208bc7eSAndroid Build Coastguard Worker 	    "Expected error for invalid alignment %zu", alignment);
25*1208bc7eSAndroid Build Coastguard Worker 
26*1208bc7eSAndroid Build Coastguard Worker 	for (alignment = sizeof(size_t); alignment < MAXALIGN;
27*1208bc7eSAndroid Build Coastguard Worker 	    alignment <<= 1) {
28*1208bc7eSAndroid Build Coastguard Worker 		set_errno(0);
29*1208bc7eSAndroid Build Coastguard Worker 		p = aligned_alloc(alignment + 1, 1);
30*1208bc7eSAndroid Build Coastguard Worker 		assert_false(p != NULL || get_errno() != EINVAL,
31*1208bc7eSAndroid Build Coastguard Worker 		    "Expected error for invalid alignment %zu",
32*1208bc7eSAndroid Build Coastguard Worker 		    alignment + 1);
33*1208bc7eSAndroid Build Coastguard Worker 	}
34*1208bc7eSAndroid Build Coastguard Worker }
35*1208bc7eSAndroid Build Coastguard Worker TEST_END
36*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_oom_errors)37*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_oom_errors) {
38*1208bc7eSAndroid Build Coastguard Worker 	size_t alignment, size;
39*1208bc7eSAndroid Build Coastguard Worker 	void *p;
40*1208bc7eSAndroid Build Coastguard Worker 
41*1208bc7eSAndroid Build Coastguard Worker #if LG_SIZEOF_PTR == 3
42*1208bc7eSAndroid Build Coastguard Worker 	alignment = UINT64_C(0x8000000000000000);
43*1208bc7eSAndroid Build Coastguard Worker 	size      = UINT64_C(0x8000000000000000);
44*1208bc7eSAndroid Build Coastguard Worker #else
45*1208bc7eSAndroid Build Coastguard Worker 	alignment = 0x80000000LU;
46*1208bc7eSAndroid Build Coastguard Worker 	size      = 0x80000000LU;
47*1208bc7eSAndroid Build Coastguard Worker #endif
48*1208bc7eSAndroid Build Coastguard Worker 	set_errno(0);
49*1208bc7eSAndroid Build Coastguard Worker 	p = aligned_alloc(alignment, size);
50*1208bc7eSAndroid Build Coastguard Worker 	assert_false(p != NULL || get_errno() != ENOMEM,
51*1208bc7eSAndroid Build Coastguard Worker 	    "Expected error for aligned_alloc(%zu, %zu)",
52*1208bc7eSAndroid Build Coastguard Worker 	    alignment, size);
53*1208bc7eSAndroid Build Coastguard Worker 
54*1208bc7eSAndroid Build Coastguard Worker #if LG_SIZEOF_PTR == 3
55*1208bc7eSAndroid Build Coastguard Worker 	alignment = UINT64_C(0x4000000000000000);
56*1208bc7eSAndroid Build Coastguard Worker 	size      = UINT64_C(0xc000000000000001);
57*1208bc7eSAndroid Build Coastguard Worker #else
58*1208bc7eSAndroid Build Coastguard Worker 	alignment = 0x40000000LU;
59*1208bc7eSAndroid Build Coastguard Worker 	size      = 0xc0000001LU;
60*1208bc7eSAndroid Build Coastguard Worker #endif
61*1208bc7eSAndroid Build Coastguard Worker 	set_errno(0);
62*1208bc7eSAndroid Build Coastguard Worker 	p = aligned_alloc(alignment, size);
63*1208bc7eSAndroid Build Coastguard Worker 	assert_false(p != NULL || get_errno() != ENOMEM,
64*1208bc7eSAndroid Build Coastguard Worker 	    "Expected error for aligned_alloc(%zu, %zu)",
65*1208bc7eSAndroid Build Coastguard Worker 	    alignment, size);
66*1208bc7eSAndroid Build Coastguard Worker 
67*1208bc7eSAndroid Build Coastguard Worker 	alignment = 0x10LU;
68*1208bc7eSAndroid Build Coastguard Worker #if LG_SIZEOF_PTR == 3
69*1208bc7eSAndroid Build Coastguard Worker 	size = UINT64_C(0xfffffffffffffff0);
70*1208bc7eSAndroid Build Coastguard Worker #else
71*1208bc7eSAndroid Build Coastguard Worker 	size = 0xfffffff0LU;
72*1208bc7eSAndroid Build Coastguard Worker #endif
73*1208bc7eSAndroid Build Coastguard Worker 	set_errno(0);
74*1208bc7eSAndroid Build Coastguard Worker 	p = aligned_alloc(alignment, size);
75*1208bc7eSAndroid Build Coastguard Worker 	assert_false(p != NULL || get_errno() != ENOMEM,
76*1208bc7eSAndroid Build Coastguard Worker 	    "Expected error for aligned_alloc(&p, %zu, %zu)",
77*1208bc7eSAndroid Build Coastguard Worker 	    alignment, size);
78*1208bc7eSAndroid Build Coastguard Worker }
79*1208bc7eSAndroid Build Coastguard Worker TEST_END
80*1208bc7eSAndroid Build Coastguard Worker 
TEST_BEGIN(test_alignment_and_size)81*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_alignment_and_size) {
82*1208bc7eSAndroid Build Coastguard Worker #define NITER 4
83*1208bc7eSAndroid Build Coastguard Worker 	size_t alignment, size, total;
84*1208bc7eSAndroid Build Coastguard Worker 	unsigned i;
85*1208bc7eSAndroid Build Coastguard Worker 	void *ps[NITER];
86*1208bc7eSAndroid Build Coastguard Worker 
87*1208bc7eSAndroid Build Coastguard Worker 	for (i = 0; i < NITER; i++) {
88*1208bc7eSAndroid Build Coastguard Worker 		ps[i] = NULL;
89*1208bc7eSAndroid Build Coastguard Worker 	}
90*1208bc7eSAndroid Build Coastguard Worker 
91*1208bc7eSAndroid Build Coastguard Worker 	for (alignment = 8;
92*1208bc7eSAndroid Build Coastguard Worker 	    alignment <= MAXALIGN;
93*1208bc7eSAndroid Build Coastguard Worker 	    alignment <<= 1) {
94*1208bc7eSAndroid Build Coastguard Worker 		total = 0;
95*1208bc7eSAndroid Build Coastguard Worker 		for (size = 1;
96*1208bc7eSAndroid Build Coastguard Worker 		    size < 3 * alignment && size < (1U << 31);
97*1208bc7eSAndroid Build Coastguard Worker 		    size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
98*1208bc7eSAndroid Build Coastguard Worker 			for (i = 0; i < NITER; i++) {
99*1208bc7eSAndroid Build Coastguard Worker 				ps[i] = aligned_alloc(alignment, size);
100*1208bc7eSAndroid Build Coastguard Worker 				if (ps[i] == NULL) {
101*1208bc7eSAndroid Build Coastguard Worker 					char buf[BUFERROR_BUF];
102*1208bc7eSAndroid Build Coastguard Worker 
103*1208bc7eSAndroid Build Coastguard Worker 					buferror(get_errno(), buf, sizeof(buf));
104*1208bc7eSAndroid Build Coastguard Worker 					test_fail(
105*1208bc7eSAndroid Build Coastguard Worker 					    "Error for alignment=%zu, "
106*1208bc7eSAndroid Build Coastguard Worker 					    "size=%zu (%#zx): %s",
107*1208bc7eSAndroid Build Coastguard Worker 					    alignment, size, size, buf);
108*1208bc7eSAndroid Build Coastguard Worker 				}
109*1208bc7eSAndroid Build Coastguard Worker 				total += malloc_usable_size(ps[i]);
110*1208bc7eSAndroid Build Coastguard Worker 				if (total >= (MAXALIGN << 1)) {
111*1208bc7eSAndroid Build Coastguard Worker 					break;
112*1208bc7eSAndroid Build Coastguard Worker 				}
113*1208bc7eSAndroid Build Coastguard Worker 			}
114*1208bc7eSAndroid Build Coastguard Worker 			for (i = 0; i < NITER; i++) {
115*1208bc7eSAndroid Build Coastguard Worker 				if (ps[i] != NULL) {
116*1208bc7eSAndroid Build Coastguard Worker 					free(ps[i]);
117*1208bc7eSAndroid Build Coastguard Worker 					ps[i] = NULL;
118*1208bc7eSAndroid Build Coastguard Worker 				}
119*1208bc7eSAndroid Build Coastguard Worker 			}
120*1208bc7eSAndroid Build Coastguard Worker 		}
121*1208bc7eSAndroid Build Coastguard Worker 		purge();
122*1208bc7eSAndroid Build Coastguard Worker 	}
123*1208bc7eSAndroid Build Coastguard Worker #undef NITER
124*1208bc7eSAndroid Build Coastguard Worker }
125*1208bc7eSAndroid Build Coastguard Worker TEST_END
126*1208bc7eSAndroid Build Coastguard Worker 
127*1208bc7eSAndroid Build Coastguard Worker int
main(void)128*1208bc7eSAndroid Build Coastguard Worker main(void) {
129*1208bc7eSAndroid Build Coastguard Worker 	return test(
130*1208bc7eSAndroid Build Coastguard Worker 	    test_alignment_errors,
131*1208bc7eSAndroid Build Coastguard Worker 	    test_oom_errors,
132*1208bc7eSAndroid Build Coastguard Worker 	    test_alignment_and_size);
133*1208bc7eSAndroid Build Coastguard Worker }
134