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