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