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