1 #include "test/jemalloc_test.h"
2
3 static unsigned
get_nsizes_impl(const char * cmd)4 get_nsizes_impl(const char *cmd)
5 {
6 unsigned ret;
7 size_t z;
8
9 z = sizeof(unsigned);
10 assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
11 "Unexpected mallctl(\"%s\", ...) failure", cmd);
12
13 return (ret);
14 }
15
16 static unsigned
get_nhuge(void)17 get_nhuge(void)
18 {
19
20 return (get_nsizes_impl("arenas.nhchunks"));
21 }
22
23 static size_t
get_size_impl(const char * cmd,size_t ind)24 get_size_impl(const char *cmd, size_t ind)
25 {
26 size_t ret;
27 size_t z;
28 size_t mib[4];
29 size_t miblen = 4;
30
31 z = sizeof(size_t);
32 assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
33 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
34 mib[2] = ind;
35 z = sizeof(size_t);
36 assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
37 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
38
39 return (ret);
40 }
41
42 static size_t
get_huge_size(size_t ind)43 get_huge_size(size_t ind)
44 {
45
46 return (get_size_impl("arenas.hchunk.0.size", ind));
47 }
48
TEST_BEGIN(test_oom)49 TEST_BEGIN(test_oom)
50 {
51 size_t hugemax, size, alignment;
52
53 hugemax = get_huge_size(get_nhuge()-1);
54
55 /*
56 * It should be impossible to allocate two objects that each consume
57 * more than half the virtual address space.
58 */
59 {
60 void *p;
61
62 p = mallocx(hugemax, 0);
63 if (p != NULL) {
64 assert_ptr_null(mallocx(hugemax, 0),
65 "Expected OOM for mallocx(size=%#zx, 0)", hugemax);
66 dallocx(p, 0);
67 }
68 }
69
70 #if LG_SIZEOF_PTR == 3
71 size = ZU(0x8000000000000000);
72 alignment = ZU(0x8000000000000000);
73 #else
74 size = ZU(0x80000000);
75 alignment = ZU(0x80000000);
76 #endif
77 assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)),
78 "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size,
79 alignment);
80 }
81 TEST_END
82
TEST_BEGIN(test_basic)83 TEST_BEGIN(test_basic)
84 {
85 #define MAXSZ (((size_t)1) << 26)
86 size_t sz;
87
88 for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {
89 size_t nsz, rsz;
90 void *p;
91 nsz = nallocx(sz, 0);
92 assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
93 p = mallocx(sz, 0);
94 assert_ptr_not_null(p, "Unexpected mallocx() error");
95 rsz = sallocx(p, 0);
96 assert_zu_ge(rsz, sz, "Real size smaller than expected");
97 assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch");
98 dallocx(p, 0);
99
100 p = mallocx(sz, 0);
101 assert_ptr_not_null(p, "Unexpected mallocx() error");
102 dallocx(p, 0);
103
104 nsz = nallocx(sz, MALLOCX_ZERO);
105 assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
106 p = mallocx(sz, MALLOCX_ZERO);
107 assert_ptr_not_null(p, "Unexpected mallocx() error");
108 rsz = sallocx(p, 0);
109 assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch");
110 dallocx(p, 0);
111 }
112 #undef MAXSZ
113 }
114 TEST_END
115
TEST_BEGIN(test_alignment_and_size)116 TEST_BEGIN(test_alignment_and_size)
117 {
118 #define MAXALIGN (((size_t)1) << 25)
119 #define NITER 4
120 size_t nsz, rsz, sz, alignment, total;
121 unsigned i;
122 void *ps[NITER];
123
124 for (i = 0; i < NITER; i++)
125 ps[i] = NULL;
126
127 for (alignment = 8;
128 alignment <= MAXALIGN;
129 alignment <<= 1) {
130 total = 0;
131 for (sz = 1;
132 sz < 3 * alignment && sz < (1U << 31);
133 sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
134 for (i = 0; i < NITER; i++) {
135 nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
136 MALLOCX_ZERO);
137 assert_zu_ne(nsz, 0,
138 "nallocx() error for alignment=%zu, "
139 "size=%zu (%#zx)", alignment, sz, sz);
140 ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
141 MALLOCX_ZERO);
142 assert_ptr_not_null(ps[i],
143 "mallocx() error for alignment=%zu, "
144 "size=%zu (%#zx)", alignment, sz, sz);
145 rsz = sallocx(ps[i], 0);
146 assert_zu_ge(rsz, sz,
147 "Real size smaller than expected for "
148 "alignment=%zu, size=%zu", alignment, sz);
149 assert_zu_eq(nsz, rsz,
150 "nallocx()/sallocx() size mismatch for "
151 "alignment=%zu, size=%zu", alignment, sz);
152 assert_ptr_null(
153 (void *)((uintptr_t)ps[i] & (alignment-1)),
154 "%p inadequately aligned for"
155 " alignment=%zu, size=%zu", ps[i],
156 alignment, sz);
157 total += rsz;
158 if (total >= (MAXALIGN << 1))
159 break;
160 }
161 for (i = 0; i < NITER; i++) {
162 if (ps[i] != NULL) {
163 dallocx(ps[i], 0);
164 ps[i] = NULL;
165 }
166 }
167 }
168 }
169 #undef MAXALIGN
170 #undef NITER
171 }
172 TEST_END
173
174 int
main(void)175 main(void)
176 {
177
178 return (test(
179 test_oom,
180 test_basic,
181 test_alignment_and_size));
182 }
183