blob: 2353c92c1faf60b9eba8b80569ae5db995d26c84 [file] [log] [blame]
Jason Evansde732962013-12-18 23:21:42 -08001#include "test/jemalloc_test.h"
2
3TEST_BEGIN(test_mallctl_errors)
4{
5 uint64_t epoch;
6 size_t sz;
7
8 assert_d_eq(mallctl("no_such_name", NULL, NULL, NULL, 0), ENOENT,
9 "mallctl() should return ENOENT for non-existent names");
10
11 assert_d_eq(mallctl("version", NULL, NULL, "0.0.0", strlen("0.0.0")),
12 EPERM, "mallctl() should return EPERM on attempt to write "
13 "read-only value");
14
Jason Evans8f61fde2016-10-27 21:31:25 -070015 assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
16 sizeof(epoch)-1), EINVAL,
17 "mallctl() should return EINVAL for input size mismatch");
18 assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
19 sizeof(epoch)+1), EINVAL,
20 "mallctl() should return EINVAL for input size mismatch");
Jason Evansde732962013-12-18 23:21:42 -080021
22 sz = sizeof(epoch)-1;
Jason Evans8f61fde2016-10-27 21:31:25 -070023 assert_d_eq(mallctl("epoch", (void *)&epoch, &sz, NULL, 0), EINVAL,
Jason Evansde732962013-12-18 23:21:42 -080024 "mallctl() should return EINVAL for output size mismatch");
25 sz = sizeof(epoch)+1;
Jason Evans8f61fde2016-10-27 21:31:25 -070026 assert_d_eq(mallctl("epoch", (void *)&epoch, &sz, NULL, 0), EINVAL,
Jason Evansde732962013-12-18 23:21:42 -080027 "mallctl() should return EINVAL for output size mismatch");
28}
29TEST_END
30
31TEST_BEGIN(test_mallctlnametomib_errors)
32{
33 size_t mib[1];
34 size_t miblen;
35
36 miblen = sizeof(mib)/sizeof(size_t);
37 assert_d_eq(mallctlnametomib("no_such_name", mib, &miblen), ENOENT,
38 "mallctlnametomib() should return ENOENT for non-existent names");
39}
40TEST_END
41
42TEST_BEGIN(test_mallctlbymib_errors)
43{
44 uint64_t epoch;
45 size_t sz;
46 size_t mib[1];
47 size_t miblen;
48
49 miblen = sizeof(mib)/sizeof(size_t);
50 assert_d_eq(mallctlnametomib("version", mib, &miblen), 0,
51 "Unexpected mallctlnametomib() failure");
52
53 assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, "0.0.0",
54 strlen("0.0.0")), EPERM, "mallctl() should return EPERM on "
55 "attempt to write read-only value");
56
57 miblen = sizeof(mib)/sizeof(size_t);
58 assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0,
59 "Unexpected mallctlnametomib() failure");
60
Jason Evans8f61fde2016-10-27 21:31:25 -070061 assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch,
Jason Evansde732962013-12-18 23:21:42 -080062 sizeof(epoch)-1), EINVAL,
63 "mallctlbymib() should return EINVAL for input size mismatch");
Jason Evans8f61fde2016-10-27 21:31:25 -070064 assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch,
Jason Evansde732962013-12-18 23:21:42 -080065 sizeof(epoch)+1), EINVAL,
66 "mallctlbymib() should return EINVAL for input size mismatch");
67
68 sz = sizeof(epoch)-1;
Jason Evans8f61fde2016-10-27 21:31:25 -070069 assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0),
70 EINVAL,
Jason Evansde732962013-12-18 23:21:42 -080071 "mallctlbymib() should return EINVAL for output size mismatch");
72 sz = sizeof(epoch)+1;
Jason Evans8f61fde2016-10-27 21:31:25 -070073 assert_d_eq(mallctlbymib(mib, miblen, (void *)&epoch, &sz, NULL, 0),
74 EINVAL,
Jason Evansde732962013-12-18 23:21:42 -080075 "mallctlbymib() should return EINVAL for output size mismatch");
76}
77TEST_END
78
79TEST_BEGIN(test_mallctl_read_write)
80{
81 uint64_t old_epoch, new_epoch;
82 size_t sz = sizeof(old_epoch);
83
84 /* Blind. */
85 assert_d_eq(mallctl("epoch", NULL, NULL, NULL, 0), 0,
86 "Unexpected mallctl() failure");
87 assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
88
89 /* Read. */
Jason Evans8f61fde2016-10-27 21:31:25 -070090 assert_d_eq(mallctl("epoch", (void *)&old_epoch, &sz, NULL, 0), 0,
Jason Evansde732962013-12-18 23:21:42 -080091 "Unexpected mallctl() failure");
92 assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
93
94 /* Write. */
Jason Evans8f61fde2016-10-27 21:31:25 -070095 assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&new_epoch,
96 sizeof(new_epoch)), 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -080097 assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
98
99 /* Read+write. */
Jason Evans8f61fde2016-10-27 21:31:25 -0700100 assert_d_eq(mallctl("epoch", (void *)&old_epoch, &sz,
101 (void *)&new_epoch, sizeof(new_epoch)), 0,
102 "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800103 assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size");
104}
105TEST_END
106
107TEST_BEGIN(test_mallctlnametomib_short_mib)
108{
109 size_t mib[4];
110 size_t miblen;
111
112 miblen = 3;
113 mib[3] = 42;
114 assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
115 "Unexpected mallctlnametomib() failure");
116 assert_zu_eq(miblen, 3, "Unexpected mib output length");
117 assert_zu_eq(mib[3], 42,
118 "mallctlnametomib() wrote past the end of the input mib");
119}
120TEST_END
121
122TEST_BEGIN(test_mallctl_config)
123{
124
Jason Evansf8290092016-02-07 14:23:22 -0800125#define TEST_MALLCTL_CONFIG(config, t) do { \
126 t oldval; \
Jason Evansde732962013-12-18 23:21:42 -0800127 size_t sz = sizeof(oldval); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700128 assert_d_eq(mallctl("config."#config, (void *)&oldval, &sz, \
129 NULL, 0), 0, "Unexpected mallctl() failure"); \
Jason Evansde732962013-12-18 23:21:42 -0800130 assert_b_eq(oldval, config_##config, "Incorrect config value"); \
131 assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
132} while (0)
133
Jason Evansf8290092016-02-07 14:23:22 -0800134 TEST_MALLCTL_CONFIG(cache_oblivious, bool);
135 TEST_MALLCTL_CONFIG(debug, bool);
136 TEST_MALLCTL_CONFIG(fill, bool);
137 TEST_MALLCTL_CONFIG(lazy_lock, bool);
138 TEST_MALLCTL_CONFIG(malloc_conf, const char *);
139 TEST_MALLCTL_CONFIG(munmap, bool);
140 TEST_MALLCTL_CONFIG(prof, bool);
141 TEST_MALLCTL_CONFIG(prof_libgcc, bool);
142 TEST_MALLCTL_CONFIG(prof_libunwind, bool);
143 TEST_MALLCTL_CONFIG(stats, bool);
144 TEST_MALLCTL_CONFIG(tcache, bool);
145 TEST_MALLCTL_CONFIG(tls, bool);
146 TEST_MALLCTL_CONFIG(utrace, bool);
147 TEST_MALLCTL_CONFIG(valgrind, bool);
148 TEST_MALLCTL_CONFIG(xmalloc, bool);
Jason Evansde732962013-12-18 23:21:42 -0800149
150#undef TEST_MALLCTL_CONFIG
151}
152TEST_END
153
154TEST_BEGIN(test_mallctl_opt)
155{
156 bool config_always = true;
157
158#define TEST_MALLCTL_OPT(t, opt, config) do { \
159 t oldval; \
160 size_t sz = sizeof(oldval); \
161 int expected = config_##config ? 0 : ENOENT; \
Jason Evans8f61fde2016-10-27 21:31:25 -0700162 int result = mallctl("opt."#opt, (void *)&oldval, &sz, NULL, \
163 0); \
Jason Evansde732962013-12-18 23:21:42 -0800164 assert_d_eq(result, expected, \
165 "Unexpected mallctl() result for opt."#opt); \
166 assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
167} while (0)
168
169 TEST_MALLCTL_OPT(bool, abort, always);
170 TEST_MALLCTL_OPT(size_t, lg_chunk, always);
171 TEST_MALLCTL_OPT(const char *, dss, always);
Jason Evans8f683b92016-02-24 11:03:40 -0800172 TEST_MALLCTL_OPT(unsigned, narenas, always);
Jason Evans243f7a02016-02-19 20:09:31 -0800173 TEST_MALLCTL_OPT(const char *, purge, always);
Jason Evansde732962013-12-18 23:21:42 -0800174 TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always);
Jason Evans243f7a02016-02-19 20:09:31 -0800175 TEST_MALLCTL_OPT(ssize_t, decay_time, always);
Jason Evansde732962013-12-18 23:21:42 -0800176 TEST_MALLCTL_OPT(bool, stats_print, always);
Guilherme Goncalves2c5cb612014-12-08 19:12:41 -0200177 TEST_MALLCTL_OPT(const char *, junk, fill);
Jason Evansde732962013-12-18 23:21:42 -0800178 TEST_MALLCTL_OPT(size_t, quarantine, fill);
179 TEST_MALLCTL_OPT(bool, redzone, fill);
180 TEST_MALLCTL_OPT(bool, zero, fill);
181 TEST_MALLCTL_OPT(bool, utrace, utrace);
Jason Evansde732962013-12-18 23:21:42 -0800182 TEST_MALLCTL_OPT(bool, xmalloc, xmalloc);
183 TEST_MALLCTL_OPT(bool, tcache, tcache);
184 TEST_MALLCTL_OPT(size_t, lg_tcache_max, tcache);
185 TEST_MALLCTL_OPT(bool, prof, prof);
186 TEST_MALLCTL_OPT(const char *, prof_prefix, prof);
187 TEST_MALLCTL_OPT(bool, prof_active, prof);
188 TEST_MALLCTL_OPT(ssize_t, lg_prof_sample, prof);
189 TEST_MALLCTL_OPT(bool, prof_accum, prof);
190 TEST_MALLCTL_OPT(ssize_t, lg_prof_interval, prof);
191 TEST_MALLCTL_OPT(bool, prof_gdump, prof);
192 TEST_MALLCTL_OPT(bool, prof_final, prof);
193 TEST_MALLCTL_OPT(bool, prof_leak, prof);
194
195#undef TEST_MALLCTL_OPT
196}
197TEST_END
198
199TEST_BEGIN(test_manpage_example)
200{
201 unsigned nbins, i;
202 size_t mib[4];
203 size_t len, miblen;
204
205 len = sizeof(nbins);
Jason Evans8f61fde2016-10-27 21:31:25 -0700206 assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &len, NULL, 0), 0,
Jason Evansde732962013-12-18 23:21:42 -0800207 "Unexpected mallctl() failure");
208
209 miblen = 4;
210 assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen), 0,
211 "Unexpected mallctlnametomib() failure");
212 for (i = 0; i < nbins; i++) {
213 size_t bin_size;
214
215 mib[2] = i;
216 len = sizeof(bin_size);
Jason Evans8f61fde2016-10-27 21:31:25 -0700217 assert_d_eq(mallctlbymib(mib, miblen, (void *)&bin_size, &len,
218 NULL, 0), 0, "Unexpected mallctlbymib() failure");
Jason Evansde732962013-12-18 23:21:42 -0800219 /* Do something with bin_size... */
220 }
221}
222TEST_END
223
Jason Evans1cb181e2015-01-29 15:30:47 -0800224TEST_BEGIN(test_tcache_none)
225{
226 void *p0, *q, *p1;
227
228 test_skip_if(!config_tcache);
229
230 /* Allocate p and q. */
231 p0 = mallocx(42, 0);
232 assert_ptr_not_null(p0, "Unexpected mallocx() failure");
233 q = mallocx(42, 0);
234 assert_ptr_not_null(q, "Unexpected mallocx() failure");
235
236 /* Deallocate p and q, but bypass the tcache for q. */
237 dallocx(p0, 0);
238 dallocx(q, MALLOCX_TCACHE_NONE);
239
240 /* Make sure that tcache-based allocation returns p, not q. */
241 p1 = mallocx(42, 0);
242 assert_ptr_not_null(p1, "Unexpected mallocx() failure");
243 assert_ptr_eq(p0, p1, "Expected tcache to allocate cached region");
244
245 /* Clean up. */
246 dallocx(p1, MALLOCX_TCACHE_NONE);
247}
248TEST_END
249
250TEST_BEGIN(test_tcache)
251{
252#define NTCACHES 10
253 unsigned tis[NTCACHES];
254 void *ps[NTCACHES];
255 void *qs[NTCACHES];
256 unsigned i;
257 size_t sz, psz, qsz;
258
259 test_skip_if(!config_tcache);
260
261 psz = 42;
262 qsz = nallocx(psz, 0) + 1;
263
264 /* Create tcaches. */
265 for (i = 0; i < NTCACHES; i++) {
266 sz = sizeof(unsigned);
Jason Evans8f61fde2016-10-27 21:31:25 -0700267 assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL,
268 0), 0, "Unexpected mallctl() failure, i=%u", i);
Jason Evans1cb181e2015-01-29 15:30:47 -0800269 }
270
Jason Evans9e561e82015-02-10 09:03:48 -0800271 /* Exercise tcache ID recycling. */
272 for (i = 0; i < NTCACHES; i++) {
Jason Evans8f61fde2016-10-27 21:31:25 -0700273 assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
274 (void *)&tis[i], sizeof(unsigned)), 0,
275 "Unexpected mallctl() failure, i=%u", i);
Jason Evans9e561e82015-02-10 09:03:48 -0800276 }
277 for (i = 0; i < NTCACHES; i++) {
278 sz = sizeof(unsigned);
Jason Evans8f61fde2016-10-27 21:31:25 -0700279 assert_d_eq(mallctl("tcache.create", (void *)&tis[i], &sz, NULL,
280 0), 0, "Unexpected mallctl() failure, i=%u", i);
Jason Evans9e561e82015-02-10 09:03:48 -0800281 }
282
Jason Evans1cb181e2015-01-29 15:30:47 -0800283 /* Flush empty tcaches. */
284 for (i = 0; i < NTCACHES; i++) {
Jason Evans8f61fde2016-10-27 21:31:25 -0700285 assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i],
Jason Evans1cb181e2015-01-29 15:30:47 -0800286 sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
287 i);
288 }
289
290 /* Cache some allocations. */
291 for (i = 0; i < NTCACHES; i++) {
292 ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
293 assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
294 i);
295 dallocx(ps[i], MALLOCX_TCACHE(tis[i]));
296
297 qs[i] = mallocx(qsz, MALLOCX_TCACHE(tis[i]));
298 assert_ptr_not_null(qs[i], "Unexpected mallocx() failure, i=%u",
299 i);
300 dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
301 }
302
303 /* Verify that tcaches allocate cached regions. */
304 for (i = 0; i < NTCACHES; i++) {
305 void *p0 = ps[i];
306 ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i]));
307 assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u",
308 i);
309 assert_ptr_eq(ps[i], p0,
310 "Expected mallocx() to allocate cached region, i=%u", i);
311 }
312
313 /* Verify that reallocation uses cached regions. */
314 for (i = 0; i < NTCACHES; i++) {
315 void *q0 = qs[i];
316 qs[i] = rallocx(ps[i], qsz, MALLOCX_TCACHE(tis[i]));
317 assert_ptr_not_null(qs[i], "Unexpected rallocx() failure, i=%u",
318 i);
319 assert_ptr_eq(qs[i], q0,
320 "Expected rallocx() to allocate cached region, i=%u", i);
321 /* Avoid undefined behavior in case of test failure. */
322 if (qs[i] == NULL)
323 qs[i] = ps[i];
324 }
325 for (i = 0; i < NTCACHES; i++)
326 dallocx(qs[i], MALLOCX_TCACHE(tis[i]));
327
328 /* Flush some non-empty tcaches. */
329 for (i = 0; i < NTCACHES/2; i++) {
Jason Evans8f61fde2016-10-27 21:31:25 -0700330 assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&tis[i],
Jason Evans1cb181e2015-01-29 15:30:47 -0800331 sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
332 i);
333 }
334
335 /* Destroy tcaches. */
336 for (i = 0; i < NTCACHES; i++) {
Jason Evans8f61fde2016-10-27 21:31:25 -0700337 assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
338 (void *)&tis[i], sizeof(unsigned)), 0,
339 "Unexpected mallctl() failure, i=%u", i);
Jason Evans1cb181e2015-01-29 15:30:47 -0800340 }
341}
342TEST_END
343
Jason Evansde732962013-12-18 23:21:42 -0800344TEST_BEGIN(test_thread_arena)
345{
346 unsigned arena_old, arena_new, narenas;
347 size_t sz = sizeof(unsigned);
348
Jason Evans8f61fde2016-10-27 21:31:25 -0700349 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
350 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800351 assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect");
352 arena_new = narenas - 1;
Jason Evans8f61fde2016-10-27 21:31:25 -0700353 assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz,
354 (void *)&arena_new, sizeof(unsigned)), 0,
355 "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800356 arena_new = 0;
Jason Evans8f61fde2016-10-27 21:31:25 -0700357 assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz,
358 (void *)&arena_new, sizeof(unsigned)), 0,
359 "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800360}
361TEST_END
362
Jason Evans8d6a3e82015-03-18 18:55:33 -0700363TEST_BEGIN(test_arena_i_lg_dirty_mult)
364{
365 ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
366 size_t sz = sizeof(ssize_t);
367
Jason Evans243f7a02016-02-19 20:09:31 -0800368 test_skip_if(opt_purge != purge_mode_ratio);
369
Jason Evans8f61fde2016-10-27 21:31:25 -0700370 assert_d_eq(mallctl("arena.0.lg_dirty_mult",
371 (void *)&orig_lg_dirty_mult, &sz, NULL, 0), 0,
372 "Unexpected mallctl() failure");
Jason Evans8d6a3e82015-03-18 18:55:33 -0700373
374 lg_dirty_mult = -2;
375 assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700376 (void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700377 "Unexpected mallctl() success");
378
379 lg_dirty_mult = (sizeof(size_t) << 3);
380 assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700381 (void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700382 "Unexpected mallctl() success");
383
384 for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
Jason Evansbd16ea42015-03-24 15:59:28 -0700385 lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult
386 = lg_dirty_mult, lg_dirty_mult++) {
Jason Evans8d6a3e82015-03-18 18:55:33 -0700387 ssize_t old_lg_dirty_mult;
388
Jason Evans8f61fde2016-10-27 21:31:25 -0700389 assert_d_eq(mallctl("arena.0.lg_dirty_mult",
390 (void *)&old_lg_dirty_mult, &sz, (void *)&lg_dirty_mult,
391 sizeof(ssize_t)), 0, "Unexpected mallctl() failure");
Jason Evans8d6a3e82015-03-18 18:55:33 -0700392 assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
393 "Unexpected old arena.0.lg_dirty_mult");
394 }
395}
396TEST_END
397
Jason Evans243f7a02016-02-19 20:09:31 -0800398TEST_BEGIN(test_arena_i_decay_time)
399{
400 ssize_t decay_time, orig_decay_time, prev_decay_time;
401 size_t sz = sizeof(ssize_t);
402
403 test_skip_if(opt_purge != purge_mode_decay);
404
Jason Evans8f61fde2016-10-27 21:31:25 -0700405 assert_d_eq(mallctl("arena.0.decay_time", (void *)&orig_decay_time, &sz,
Jason Evans243f7a02016-02-19 20:09:31 -0800406 NULL, 0), 0, "Unexpected mallctl() failure");
407
408 decay_time = -2;
409 assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700410 (void *)&decay_time, sizeof(ssize_t)), EFAULT,
Jason Evans243f7a02016-02-19 20:09:31 -0800411 "Unexpected mallctl() success");
412
Jason Evans9bad0792016-02-21 11:25:02 -0800413 decay_time = 0x7fffffff;
Jason Evans243f7a02016-02-19 20:09:31 -0800414 assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700415 (void *)&decay_time, sizeof(ssize_t)), 0,
Jason Evans243f7a02016-02-19 20:09:31 -0800416 "Unexpected mallctl() failure");
417
418 for (prev_decay_time = decay_time, decay_time = -1;
419 decay_time < 20; prev_decay_time = decay_time, decay_time++) {
420 ssize_t old_decay_time;
421
Jason Evans8f61fde2016-10-27 21:31:25 -0700422 assert_d_eq(mallctl("arena.0.decay_time", (void *)&old_decay_time,
423 &sz, (void *)&decay_time, sizeof(ssize_t)), 0,
Jason Evans243f7a02016-02-19 20:09:31 -0800424 "Unexpected mallctl() failure");
425 assert_zd_eq(old_decay_time, prev_decay_time,
426 "Unexpected old arena.0.decay_time");
427 }
428}
429TEST_END
430
Jason Evansde732962013-12-18 23:21:42 -0800431TEST_BEGIN(test_arena_i_purge)
432{
433 unsigned narenas;
434 size_t sz = sizeof(unsigned);
435 size_t mib[3];
436 size_t miblen = 3;
437
438 assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
439 "Unexpected mallctl() failure");
440
Jason Evans8f61fde2016-10-27 21:31:25 -0700441 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
442 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800443 assert_d_eq(mallctlnametomib("arena.0.purge", mib, &miblen), 0,
444 "Unexpected mallctlnametomib() failure");
445 mib[1] = narenas;
446 assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
447 "Unexpected mallctlbymib() failure");
448}
449TEST_END
450
Jason Evans243f7a02016-02-19 20:09:31 -0800451TEST_BEGIN(test_arena_i_decay)
452{
453 unsigned narenas;
454 size_t sz = sizeof(unsigned);
455 size_t mib[3];
456 size_t miblen = 3;
457
458 assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
459 "Unexpected mallctl() failure");
460
Jason Evans8f61fde2016-10-27 21:31:25 -0700461 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
462 0, "Unexpected mallctl() failure");
Jason Evans243f7a02016-02-19 20:09:31 -0800463 assert_d_eq(mallctlnametomib("arena.0.decay", mib, &miblen), 0,
464 "Unexpected mallctlnametomib() failure");
465 mib[1] = narenas;
466 assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
467 "Unexpected mallctlbymib() failure");
468}
469TEST_END
470
Jason Evansde732962013-12-18 23:21:42 -0800471TEST_BEGIN(test_arena_i_dss)
472{
473 const char *dss_prec_old, *dss_prec_new;
474 size_t sz = sizeof(dss_prec_old);
Jason Evans4d434ad2014-04-15 12:09:48 -0700475 size_t mib[3];
476 size_t miblen;
Jason Evansde732962013-12-18 23:21:42 -0800477
Jason Evans4d434ad2014-04-15 12:09:48 -0700478 miblen = sizeof(mib)/sizeof(size_t);
479 assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0,
480 "Unexpected mallctlnametomib() error");
481
482 dss_prec_new = "disabled";
Jason Evans8f61fde2016-10-27 21:31:25 -0700483 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
484 (void *)&dss_prec_new, sizeof(dss_prec_new)), 0,
485 "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800486 assert_str_ne(dss_prec_old, "primary",
487 "Unexpected default for dss precedence");
488
Jason Evans8f61fde2016-10-27 21:31:25 -0700489 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz,
490 (void *)&dss_prec_old, sizeof(dss_prec_old)), 0,
Jason Evans586c8ed2014-08-15 12:20:20 -0700491 "Unexpected mallctl() failure");
Jason Evans8f61fde2016-10-27 21:31:25 -0700492
493 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL,
494 0), 0, "Unexpected mallctl() failure");
Jason Evans586c8ed2014-08-15 12:20:20 -0700495 assert_str_ne(dss_prec_old, "primary",
496 "Unexpected value for dss precedence");
497
Jason Evans4d434ad2014-04-15 12:09:48 -0700498 mib[1] = narenas_total_get();
499 dss_prec_new = "disabled";
Jason Evans8f61fde2016-10-27 21:31:25 -0700500 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
501 (void *)&dss_prec_new, sizeof(dss_prec_new)), 0,
502 "Unexpected mallctl() failure");
Jason Evans4d434ad2014-04-15 12:09:48 -0700503 assert_str_ne(dss_prec_old, "primary",
504 "Unexpected default for dss precedence");
Jason Evans586c8ed2014-08-15 12:20:20 -0700505
Jason Evans8f61fde2016-10-27 21:31:25 -0700506 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_new, &sz,
507 (void *)&dss_prec_old, sizeof(dss_prec_new)), 0,
Jason Evans586c8ed2014-08-15 12:20:20 -0700508 "Unexpected mallctl() failure");
Jason Evans8f61fde2016-10-27 21:31:25 -0700509
510 assert_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz, NULL,
511 0), 0, "Unexpected mallctl() failure");
Jason Evans586c8ed2014-08-15 12:20:20 -0700512 assert_str_ne(dss_prec_old, "primary",
513 "Unexpected value for dss precedence");
Jason Evansde732962013-12-18 23:21:42 -0800514}
515TEST_END
516
Jason Evansde732962013-12-18 23:21:42 -0800517TEST_BEGIN(test_arenas_initialized)
518{
519 unsigned narenas;
520 size_t sz = sizeof(narenas);
521
Jason Evans8f61fde2016-10-27 21:31:25 -0700522 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
523 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800524 {
Mike Hommeyf41f1432014-05-21 17:24:08 +0900525 VARIABLE_ARRAY(bool, initialized, narenas);
Jason Evansde732962013-12-18 23:21:42 -0800526
527 sz = narenas * sizeof(bool);
Jason Evans8f61fde2016-10-27 21:31:25 -0700528 assert_d_eq(mallctl("arenas.initialized", (void *)initialized,
529 &sz, NULL, 0), 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800530 }
531}
532TEST_END
533
Jason Evans8d6a3e82015-03-18 18:55:33 -0700534TEST_BEGIN(test_arenas_lg_dirty_mult)
535{
536 ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult;
537 size_t sz = sizeof(ssize_t);
538
Jason Evans243f7a02016-02-19 20:09:31 -0800539 test_skip_if(opt_purge != purge_mode_ratio);
540
Jason Evans8f61fde2016-10-27 21:31:25 -0700541 assert_d_eq(mallctl("arenas.lg_dirty_mult", (void *)&orig_lg_dirty_mult,
542 &sz, NULL, 0), 0, "Unexpected mallctl() failure");
Jason Evans8d6a3e82015-03-18 18:55:33 -0700543
544 lg_dirty_mult = -2;
545 assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700546 (void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700547 "Unexpected mallctl() success");
548
549 lg_dirty_mult = (sizeof(size_t) << 3);
550 assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700551 (void *)&lg_dirty_mult, sizeof(ssize_t)), EFAULT,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700552 "Unexpected mallctl() success");
553
554 for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1;
Jason Evansbd16ea42015-03-24 15:59:28 -0700555 lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult =
Jason Evans8d6a3e82015-03-18 18:55:33 -0700556 lg_dirty_mult, lg_dirty_mult++) {
557 ssize_t old_lg_dirty_mult;
558
Jason Evans8f61fde2016-10-27 21:31:25 -0700559 assert_d_eq(mallctl("arenas.lg_dirty_mult",
560 (void *)&old_lg_dirty_mult, &sz, (void *)&lg_dirty_mult,
561 sizeof(ssize_t)), 0, "Unexpected mallctl() failure");
Jason Evans8d6a3e82015-03-18 18:55:33 -0700562 assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult,
563 "Unexpected old arenas.lg_dirty_mult");
564 }
565}
566TEST_END
567
Jason Evans243f7a02016-02-19 20:09:31 -0800568TEST_BEGIN(test_arenas_decay_time)
569{
570 ssize_t decay_time, orig_decay_time, prev_decay_time;
571 size_t sz = sizeof(ssize_t);
572
573 test_skip_if(opt_purge != purge_mode_decay);
574
Jason Evans8f61fde2016-10-27 21:31:25 -0700575 assert_d_eq(mallctl("arenas.decay_time", (void *)&orig_decay_time, &sz,
Jason Evans243f7a02016-02-19 20:09:31 -0800576 NULL, 0), 0, "Unexpected mallctl() failure");
577
578 decay_time = -2;
579 assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700580 (void *)&decay_time, sizeof(ssize_t)), EFAULT,
Jason Evans243f7a02016-02-19 20:09:31 -0800581 "Unexpected mallctl() success");
582
Jason Evans9bad0792016-02-21 11:25:02 -0800583 decay_time = 0x7fffffff;
Jason Evans243f7a02016-02-19 20:09:31 -0800584 assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
Jason Evans8f61fde2016-10-27 21:31:25 -0700585 (void *)&decay_time, sizeof(ssize_t)), 0,
Jason Evans243f7a02016-02-19 20:09:31 -0800586 "Expected mallctl() failure");
587
588 for (prev_decay_time = decay_time, decay_time = -1;
589 decay_time < 20; prev_decay_time = decay_time, decay_time++) {
590 ssize_t old_decay_time;
591
Jason Evans8f61fde2016-10-27 21:31:25 -0700592 assert_d_eq(mallctl("arenas.decay_time",
593 (void *)&old_decay_time, &sz, (void *)&decay_time,
594 sizeof(ssize_t)), 0, "Unexpected mallctl() failure");
Jason Evans243f7a02016-02-19 20:09:31 -0800595 assert_zd_eq(old_decay_time, prev_decay_time,
596 "Unexpected old arenas.decay_time");
597 }
598}
599TEST_END
600
Jason Evansde732962013-12-18 23:21:42 -0800601TEST_BEGIN(test_arenas_constants)
602{
603
604#define TEST_ARENAS_CONSTANT(t, name, expected) do { \
605 t name; \
606 size_t sz = sizeof(t); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700607 assert_d_eq(mallctl("arenas."#name, (void *)&name, &sz, NULL, \
608 0), 0, "Unexpected mallctl() failure"); \
Jason Evansde732962013-12-18 23:21:42 -0800609 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
610} while (0)
611
612 TEST_ARENAS_CONSTANT(size_t, quantum, QUANTUM);
613 TEST_ARENAS_CONSTANT(size_t, page, PAGE);
614 TEST_ARENAS_CONSTANT(unsigned, nbins, NBINS);
Jason Evans3c4d92e2014-10-12 22:53:59 -0700615 TEST_ARENAS_CONSTANT(unsigned, nlruns, nlclasses);
616 TEST_ARENAS_CONSTANT(unsigned, nhchunks, nhclasses);
Jason Evansde732962013-12-18 23:21:42 -0800617
618#undef TEST_ARENAS_CONSTANT
619}
620TEST_END
621
622TEST_BEGIN(test_arenas_bin_constants)
623{
624
625#define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \
626 t name; \
627 size_t sz = sizeof(t); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700628 assert_d_eq(mallctl("arenas.bin.0."#name, (void *)&name, &sz, \
629 NULL, 0), 0, "Unexpected mallctl() failure"); \
Jason Evansde732962013-12-18 23:21:42 -0800630 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
631} while (0)
632
633 TEST_ARENAS_BIN_CONSTANT(size_t, size, arena_bin_info[0].reg_size);
634 TEST_ARENAS_BIN_CONSTANT(uint32_t, nregs, arena_bin_info[0].nregs);
635 TEST_ARENAS_BIN_CONSTANT(size_t, run_size, arena_bin_info[0].run_size);
636
637#undef TEST_ARENAS_BIN_CONSTANT
638}
639TEST_END
640
641TEST_BEGIN(test_arenas_lrun_constants)
642{
643
644#define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \
645 t name; \
646 size_t sz = sizeof(t); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700647 assert_d_eq(mallctl("arenas.lrun.0."#name, (void *)&name, &sz, \
648 NULL, 0), 0, "Unexpected mallctl() failure"); \
Jason Evansde732962013-12-18 23:21:42 -0800649 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
650} while (0)
651
Jason Evansfc0b3b72014-10-09 17:54:06 -0700652 TEST_ARENAS_LRUN_CONSTANT(size_t, size, LARGE_MINCLASS);
Jason Evansde732962013-12-18 23:21:42 -0800653
654#undef TEST_ARENAS_LRUN_CONSTANT
655}
656TEST_END
657
Jason Evans3c4d92e2014-10-12 22:53:59 -0700658TEST_BEGIN(test_arenas_hchunk_constants)
659{
660
661#define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \
662 t name; \
663 size_t sz = sizeof(t); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700664 assert_d_eq(mallctl("arenas.hchunk.0."#name, (void *)&name, \
665 &sz, NULL, 0), 0, "Unexpected mallctl() failure"); \
Jason Evans3c4d92e2014-10-12 22:53:59 -0700666 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
667} while (0)
668
669 TEST_ARENAS_HCHUNK_CONSTANT(size_t, size, chunksize);
670
671#undef TEST_ARENAS_HCHUNK_CONSTANT
672}
673TEST_END
674
Jason Evansde732962013-12-18 23:21:42 -0800675TEST_BEGIN(test_arenas_extend)
676{
677 unsigned narenas_before, arena, narenas_after;
678 size_t sz = sizeof(unsigned);
679
Jason Evans8f61fde2016-10-27 21:31:25 -0700680 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_before, &sz,
681 NULL, 0), 0, "Unexpected mallctl() failure");
682 assert_d_eq(mallctl("arenas.extend", (void *)&arena, &sz, NULL, 0), 0,
Jason Evansde732962013-12-18 23:21:42 -0800683 "Unexpected mallctl() failure");
Jason Evans8f61fde2016-10-27 21:31:25 -0700684 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_after, &sz, NULL,
685 0), 0, "Unexpected mallctl() failure");
Jason Evansde732962013-12-18 23:21:42 -0800686
687 assert_u_eq(narenas_before+1, narenas_after,
688 "Unexpected number of arenas before versus after extension");
689 assert_u_eq(arena, narenas_after-1, "Unexpected arena index");
690}
691TEST_END
692
693TEST_BEGIN(test_stats_arenas)
694{
695
696#define TEST_STATS_ARENAS(t, name) do { \
697 t name; \
698 size_t sz = sizeof(t); \
Jason Evans8f61fde2016-10-27 21:31:25 -0700699 assert_d_eq(mallctl("stats.arenas.0."#name, (void *)&name, &sz, \
700 NULL, 0), 0, "Unexpected mallctl() failure"); \
Jason Evansde732962013-12-18 23:21:42 -0800701} while (0)
702
Jason Evansde732962013-12-18 23:21:42 -0800703 TEST_STATS_ARENAS(unsigned, nthreads);
Jason Evans3c07f802016-02-27 20:40:13 -0800704 TEST_STATS_ARENAS(const char *, dss);
705 TEST_STATS_ARENAS(ssize_t, lg_dirty_mult);
706 TEST_STATS_ARENAS(ssize_t, decay_time);
Jason Evansde732962013-12-18 23:21:42 -0800707 TEST_STATS_ARENAS(size_t, pactive);
708 TEST_STATS_ARENAS(size_t, pdirty);
709
710#undef TEST_STATS_ARENAS
711}
712TEST_END
713
714int
715main(void)
716{
717
718 return (test(
719 test_mallctl_errors,
720 test_mallctlnametomib_errors,
721 test_mallctlbymib_errors,
722 test_mallctl_read_write,
723 test_mallctlnametomib_short_mib,
724 test_mallctl_config,
725 test_mallctl_opt,
726 test_manpage_example,
Jason Evans1cb181e2015-01-29 15:30:47 -0800727 test_tcache_none,
728 test_tcache,
Jason Evansde732962013-12-18 23:21:42 -0800729 test_thread_arena,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700730 test_arena_i_lg_dirty_mult,
Jason Evans243f7a02016-02-19 20:09:31 -0800731 test_arena_i_decay_time,
Jason Evansde732962013-12-18 23:21:42 -0800732 test_arena_i_purge,
Jason Evans243f7a02016-02-19 20:09:31 -0800733 test_arena_i_decay,
Jason Evansde732962013-12-18 23:21:42 -0800734 test_arena_i_dss,
Jason Evansde732962013-12-18 23:21:42 -0800735 test_arenas_initialized,
Jason Evans8d6a3e82015-03-18 18:55:33 -0700736 test_arenas_lg_dirty_mult,
Jason Evans243f7a02016-02-19 20:09:31 -0800737 test_arenas_decay_time,
Jason Evansde732962013-12-18 23:21:42 -0800738 test_arenas_constants,
739 test_arenas_bin_constants,
740 test_arenas_lrun_constants,
Jason Evans3c4d92e2014-10-12 22:53:59 -0700741 test_arenas_hchunk_constants,
Jason Evansde732962013-12-18 23:21:42 -0800742 test_arenas_extend,
743 test_stats_arenas));
744}