1 #include "test/jemalloc_test.h"
3 TEST_BEGIN(test_mallctl_errors
)
8 assert_d_eq(mallctl("no_such_name", NULL
, NULL
, NULL
, 0), ENOENT
,
9 "mallctl() should return ENOENT for non-existent names");
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 "
15 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");
23 assert_d_eq(mallctl("epoch", (void *)&epoch
, &sz
, NULL
, 0), EINVAL
,
24 "mallctl() should return EINVAL for output size mismatch");
26 assert_d_eq(mallctl("epoch", (void *)&epoch
, &sz
, NULL
, 0), EINVAL
,
27 "mallctl() should return EINVAL for output size mismatch");
31 TEST_BEGIN(test_mallctlnametomib_errors
)
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");
42 TEST_BEGIN(test_mallctlbymib_errors
)
49 miblen
= sizeof(mib
)/sizeof(size_t);
50 assert_d_eq(mallctlnametomib("version", mib
, &miblen
), 0,
51 "Unexpected mallctlnametomib() failure");
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");
57 miblen
= sizeof(mib
)/sizeof(size_t);
58 assert_d_eq(mallctlnametomib("epoch", mib
, &miblen
), 0,
59 "Unexpected mallctlnametomib() failure");
61 assert_d_eq(mallctlbymib(mib
, miblen
, NULL
, NULL
, (void *)&epoch
,
62 sizeof(epoch
)-1), EINVAL
,
63 "mallctlbymib() should return EINVAL for input size mismatch");
64 assert_d_eq(mallctlbymib(mib
, miblen
, NULL
, NULL
, (void *)&epoch
,
65 sizeof(epoch
)+1), EINVAL
,
66 "mallctlbymib() should return EINVAL for input size mismatch");
69 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&epoch
, &sz
, NULL
, 0),
71 "mallctlbymib() should return EINVAL for output size mismatch");
73 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&epoch
, &sz
, NULL
, 0),
75 "mallctlbymib() should return EINVAL for output size mismatch");
79 TEST_BEGIN(test_mallctl_read_write
)
81 uint64_t old_epoch
, new_epoch
;
82 size_t sz
= sizeof(old_epoch
);
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");
90 assert_d_eq(mallctl("epoch", (void *)&old_epoch
, &sz
, NULL
, 0), 0,
91 "Unexpected mallctl() failure");
92 assert_zu_eq(sz
, sizeof(old_epoch
), "Unexpected output size");
95 assert_d_eq(mallctl("epoch", NULL
, NULL
, (void *)&new_epoch
,
96 sizeof(new_epoch
)), 0, "Unexpected mallctl() failure");
97 assert_zu_eq(sz
, sizeof(old_epoch
), "Unexpected output size");
100 assert_d_eq(mallctl("epoch", (void *)&old_epoch
, &sz
,
101 (void *)&new_epoch
, sizeof(new_epoch
)), 0,
102 "Unexpected mallctl() failure");
103 assert_zu_eq(sz
, sizeof(old_epoch
), "Unexpected output size");
107 TEST_BEGIN(test_mallctlnametomib_short_mib
)
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");
122 TEST_BEGIN(test_mallctl_config
)
125 #define TEST_MALLCTL_CONFIG(config, t) do { \
127 size_t sz = sizeof(oldval); \
128 assert_d_eq(mallctl("config."#config, (void *)&oldval, &sz, \
129 NULL, 0), 0, "Unexpected mallctl() failure"); \
130 assert_b_eq(oldval, config_##config, "Incorrect config value"); \
131 assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
134 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(thp
, bool);
146 TEST_MALLCTL_CONFIG(tls
, bool);
147 TEST_MALLCTL_CONFIG(utrace
, bool);
148 TEST_MALLCTL_CONFIG(valgrind
, bool);
149 TEST_MALLCTL_CONFIG(xmalloc
, bool);
151 #undef TEST_MALLCTL_CONFIG
155 TEST_BEGIN(test_mallctl_opt
)
157 bool config_always
= true;
159 #define TEST_MALLCTL_OPT(t, opt, config) do { \
161 size_t sz = sizeof(oldval); \
162 int expected = config_##config ? 0 : ENOENT; \
163 int result = mallctl("opt."#opt, (void *)&oldval, &sz, NULL, \
165 assert_d_eq(result, expected, \
166 "Unexpected mallctl() result for opt."#opt); \
167 assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \
170 TEST_MALLCTL_OPT(bool, abort
, always
);
171 TEST_MALLCTL_OPT(size_t, lg_chunk
, always
);
172 TEST_MALLCTL_OPT(const char *, dss
, always
);
173 TEST_MALLCTL_OPT(unsigned, narenas
, always
);
174 TEST_MALLCTL_OPT(const char *, purge
, always
);
175 TEST_MALLCTL_OPT(ssize_t
, lg_dirty_mult
, always
);
176 TEST_MALLCTL_OPT(ssize_t
, decay_time
, always
);
177 TEST_MALLCTL_OPT(bool, stats_print
, always
);
178 TEST_MALLCTL_OPT(const char *, junk
, fill
);
179 TEST_MALLCTL_OPT(size_t, quarantine
, fill
);
180 TEST_MALLCTL_OPT(bool, redzone
, fill
);
181 TEST_MALLCTL_OPT(bool, zero
, fill
);
182 TEST_MALLCTL_OPT(bool, utrace
, utrace
);
183 TEST_MALLCTL_OPT(bool, xmalloc
, xmalloc
);
184 TEST_MALLCTL_OPT(bool, tcache
, tcache
);
185 TEST_MALLCTL_OPT(size_t, lg_tcache_max
, tcache
);
186 TEST_MALLCTL_OPT(bool, thp
, thp
);
187 TEST_MALLCTL_OPT(bool, prof
, prof
);
188 TEST_MALLCTL_OPT(const char *, prof_prefix
, prof
);
189 TEST_MALLCTL_OPT(bool, prof_active
, prof
);
190 TEST_MALLCTL_OPT(ssize_t
, lg_prof_sample
, prof
);
191 TEST_MALLCTL_OPT(bool, prof_accum
, prof
);
192 TEST_MALLCTL_OPT(ssize_t
, lg_prof_interval
, prof
);
193 TEST_MALLCTL_OPT(bool, prof_gdump
, prof
);
194 TEST_MALLCTL_OPT(bool, prof_final
, prof
);
195 TEST_MALLCTL_OPT(bool, prof_leak
, prof
);
197 #undef TEST_MALLCTL_OPT
201 TEST_BEGIN(test_manpage_example
)
208 assert_d_eq(mallctl("arenas.nbins", (void *)&nbins
, &len
, NULL
, 0), 0,
209 "Unexpected mallctl() failure");
212 assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib
, &miblen
), 0,
213 "Unexpected mallctlnametomib() failure");
214 for (i
= 0; i
< nbins
; i
++) {
218 len
= sizeof(bin_size
);
219 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&bin_size
, &len
,
220 NULL
, 0), 0, "Unexpected mallctlbymib() failure");
221 /* Do something with bin_size... */
226 TEST_BEGIN(test_tcache_none
)
230 test_skip_if(!config_tcache
);
232 /* Allocate p and q. */
234 assert_ptr_not_null(p0
, "Unexpected mallocx() failure");
236 assert_ptr_not_null(q
, "Unexpected mallocx() failure");
238 /* Deallocate p and q, but bypass the tcache for q. */
240 dallocx(q
, MALLOCX_TCACHE_NONE
);
242 /* Make sure that tcache-based allocation returns p, not q. */
244 assert_ptr_not_null(p1
, "Unexpected mallocx() failure");
245 assert_ptr_eq(p0
, p1
, "Expected tcache to allocate cached region");
248 dallocx(p1
, MALLOCX_TCACHE_NONE
);
252 TEST_BEGIN(test_tcache
)
255 unsigned tis
[NTCACHES
];
261 test_skip_if(!config_tcache
);
264 qsz
= nallocx(psz
, 0) + 1;
266 /* Create tcaches. */
267 for (i
= 0; i
< NTCACHES
; i
++) {
268 sz
= sizeof(unsigned);
269 assert_d_eq(mallctl("tcache.create", (void *)&tis
[i
], &sz
, NULL
,
270 0), 0, "Unexpected mallctl() failure, i=%u", i
);
273 /* Exercise tcache ID recycling. */
274 for (i
= 0; i
< NTCACHES
; i
++) {
275 assert_d_eq(mallctl("tcache.destroy", NULL
, NULL
,
276 (void *)&tis
[i
], sizeof(unsigned)), 0,
277 "Unexpected mallctl() failure, i=%u", i
);
279 for (i
= 0; i
< NTCACHES
; i
++) {
280 sz
= sizeof(unsigned);
281 assert_d_eq(mallctl("tcache.create", (void *)&tis
[i
], &sz
, NULL
,
282 0), 0, "Unexpected mallctl() failure, i=%u", i
);
285 /* Flush empty tcaches. */
286 for (i
= 0; i
< NTCACHES
; i
++) {
287 assert_d_eq(mallctl("tcache.flush", NULL
, NULL
, (void *)&tis
[i
],
288 sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
292 /* Cache some allocations. */
293 for (i
= 0; i
< NTCACHES
; i
++) {
294 ps
[i
] = mallocx(psz
, MALLOCX_TCACHE(tis
[i
]));
295 assert_ptr_not_null(ps
[i
], "Unexpected mallocx() failure, i=%u",
297 dallocx(ps
[i
], MALLOCX_TCACHE(tis
[i
]));
299 qs
[i
] = mallocx(qsz
, MALLOCX_TCACHE(tis
[i
]));
300 assert_ptr_not_null(qs
[i
], "Unexpected mallocx() failure, i=%u",
302 dallocx(qs
[i
], MALLOCX_TCACHE(tis
[i
]));
305 /* Verify that tcaches allocate cached regions. */
306 for (i
= 0; i
< NTCACHES
; i
++) {
308 ps
[i
] = mallocx(psz
, MALLOCX_TCACHE(tis
[i
]));
309 assert_ptr_not_null(ps
[i
], "Unexpected mallocx() failure, i=%u",
311 assert_ptr_eq(ps
[i
], p0
,
312 "Expected mallocx() to allocate cached region, i=%u", i
);
315 /* Verify that reallocation uses cached regions. */
316 for (i
= 0; i
< NTCACHES
; i
++) {
318 qs
[i
] = rallocx(ps
[i
], qsz
, MALLOCX_TCACHE(tis
[i
]));
319 assert_ptr_not_null(qs
[i
], "Unexpected rallocx() failure, i=%u",
321 assert_ptr_eq(qs
[i
], q0
,
322 "Expected rallocx() to allocate cached region, i=%u", i
);
323 /* Avoid undefined behavior in case of test failure. */
327 for (i
= 0; i
< NTCACHES
; i
++)
328 dallocx(qs
[i
], MALLOCX_TCACHE(tis
[i
]));
330 /* Flush some non-empty tcaches. */
331 for (i
= 0; i
< NTCACHES
/2; i
++) {
332 assert_d_eq(mallctl("tcache.flush", NULL
, NULL
, (void *)&tis
[i
],
333 sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u",
337 /* Destroy tcaches. */
338 for (i
= 0; i
< NTCACHES
; i
++) {
339 assert_d_eq(mallctl("tcache.destroy", NULL
, NULL
,
340 (void *)&tis
[i
], sizeof(unsigned)), 0,
341 "Unexpected mallctl() failure, i=%u", i
);
346 TEST_BEGIN(test_thread_arena
)
348 unsigned arena_old
, arena_new
, narenas
;
349 size_t sz
= sizeof(unsigned);
351 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas
, &sz
, NULL
, 0),
352 0, "Unexpected mallctl() failure");
353 assert_u_eq(narenas
, opt_narenas
, "Number of arenas incorrect");
354 arena_new
= narenas
- 1;
355 assert_d_eq(mallctl("thread.arena", (void *)&arena_old
, &sz
,
356 (void *)&arena_new
, sizeof(unsigned)), 0,
357 "Unexpected mallctl() failure");
359 assert_d_eq(mallctl("thread.arena", (void *)&arena_old
, &sz
,
360 (void *)&arena_new
, sizeof(unsigned)), 0,
361 "Unexpected mallctl() failure");
365 TEST_BEGIN(test_arena_i_lg_dirty_mult
)
367 ssize_t lg_dirty_mult
, orig_lg_dirty_mult
, prev_lg_dirty_mult
;
368 size_t sz
= sizeof(ssize_t
);
370 test_skip_if(opt_purge
!= purge_mode_ratio
);
372 assert_d_eq(mallctl("arena.0.lg_dirty_mult",
373 (void *)&orig_lg_dirty_mult
, &sz
, NULL
, 0), 0,
374 "Unexpected mallctl() failure");
377 assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL
, NULL
,
378 (void *)&lg_dirty_mult
, sizeof(ssize_t
)), EFAULT
,
379 "Unexpected mallctl() success");
381 lg_dirty_mult
= (sizeof(size_t) << 3);
382 assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL
, NULL
,
383 (void *)&lg_dirty_mult
, sizeof(ssize_t
)), EFAULT
,
384 "Unexpected mallctl() success");
386 for (prev_lg_dirty_mult
= orig_lg_dirty_mult
, lg_dirty_mult
= -1;
387 lg_dirty_mult
< (ssize_t
)(sizeof(size_t) << 3); prev_lg_dirty_mult
388 = lg_dirty_mult
, lg_dirty_mult
++) {
389 ssize_t old_lg_dirty_mult
;
391 assert_d_eq(mallctl("arena.0.lg_dirty_mult",
392 (void *)&old_lg_dirty_mult
, &sz
, (void *)&lg_dirty_mult
,
393 sizeof(ssize_t
)), 0, "Unexpected mallctl() failure");
394 assert_zd_eq(old_lg_dirty_mult
, prev_lg_dirty_mult
,
395 "Unexpected old arena.0.lg_dirty_mult");
400 TEST_BEGIN(test_arena_i_decay_time
)
402 ssize_t decay_time
, orig_decay_time
, prev_decay_time
;
403 size_t sz
= sizeof(ssize_t
);
405 test_skip_if(opt_purge
!= purge_mode_decay
);
407 assert_d_eq(mallctl("arena.0.decay_time", (void *)&orig_decay_time
, &sz
,
408 NULL
, 0), 0, "Unexpected mallctl() failure");
411 assert_d_eq(mallctl("arena.0.decay_time", NULL
, NULL
,
412 (void *)&decay_time
, sizeof(ssize_t
)), EFAULT
,
413 "Unexpected mallctl() success");
415 decay_time
= 0x7fffffff;
416 assert_d_eq(mallctl("arena.0.decay_time", NULL
, NULL
,
417 (void *)&decay_time
, sizeof(ssize_t
)), 0,
418 "Unexpected mallctl() failure");
420 for (prev_decay_time
= decay_time
, decay_time
= -1;
421 decay_time
< 20; prev_decay_time
= decay_time
, decay_time
++) {
422 ssize_t old_decay_time
;
424 assert_d_eq(mallctl("arena.0.decay_time", (void *)&old_decay_time
,
425 &sz
, (void *)&decay_time
, sizeof(ssize_t
)), 0,
426 "Unexpected mallctl() failure");
427 assert_zd_eq(old_decay_time
, prev_decay_time
,
428 "Unexpected old arena.0.decay_time");
433 TEST_BEGIN(test_arena_i_purge
)
436 size_t sz
= sizeof(unsigned);
440 assert_d_eq(mallctl("arena.0.purge", NULL
, NULL
, NULL
, 0), 0,
441 "Unexpected mallctl() failure");
443 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas
, &sz
, NULL
, 0),
444 0, "Unexpected mallctl() failure");
445 assert_d_eq(mallctlnametomib("arena.0.purge", mib
, &miblen
), 0,
446 "Unexpected mallctlnametomib() failure");
448 assert_d_eq(mallctlbymib(mib
, miblen
, NULL
, NULL
, NULL
, 0), 0,
449 "Unexpected mallctlbymib() failure");
453 TEST_BEGIN(test_arena_i_decay
)
456 size_t sz
= sizeof(unsigned);
460 assert_d_eq(mallctl("arena.0.decay", NULL
, NULL
, NULL
, 0), 0,
461 "Unexpected mallctl() failure");
463 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas
, &sz
, NULL
, 0),
464 0, "Unexpected mallctl() failure");
465 assert_d_eq(mallctlnametomib("arena.0.decay", mib
, &miblen
), 0,
466 "Unexpected mallctlnametomib() failure");
468 assert_d_eq(mallctlbymib(mib
, miblen
, NULL
, NULL
, NULL
, 0), 0,
469 "Unexpected mallctlbymib() failure");
473 TEST_BEGIN(test_arena_i_dss
)
475 const char *dss_prec_old
, *dss_prec_new
;
476 size_t sz
= sizeof(dss_prec_old
);
480 miblen
= sizeof(mib
)/sizeof(size_t);
481 assert_d_eq(mallctlnametomib("arena.0.dss", mib
, &miblen
), 0,
482 "Unexpected mallctlnametomib() error");
484 dss_prec_new
= "disabled";
485 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_old
, &sz
,
486 (void *)&dss_prec_new
, sizeof(dss_prec_new
)), 0,
487 "Unexpected mallctl() failure");
488 assert_str_ne(dss_prec_old
, "primary",
489 "Unexpected default for dss precedence");
491 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_new
, &sz
,
492 (void *)&dss_prec_old
, sizeof(dss_prec_old
)), 0,
493 "Unexpected mallctl() failure");
495 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_old
, &sz
, NULL
,
496 0), 0, "Unexpected mallctl() failure");
497 assert_str_ne(dss_prec_old
, "primary",
498 "Unexpected value for dss precedence");
500 mib
[1] = narenas_total_get();
501 dss_prec_new
= "disabled";
502 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_old
, &sz
,
503 (void *)&dss_prec_new
, sizeof(dss_prec_new
)), 0,
504 "Unexpected mallctl() failure");
505 assert_str_ne(dss_prec_old
, "primary",
506 "Unexpected default for dss precedence");
508 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_new
, &sz
,
509 (void *)&dss_prec_old
, sizeof(dss_prec_new
)), 0,
510 "Unexpected mallctl() failure");
512 assert_d_eq(mallctlbymib(mib
, miblen
, (void *)&dss_prec_old
, &sz
, NULL
,
513 0), 0, "Unexpected mallctl() failure");
514 assert_str_ne(dss_prec_old
, "primary",
515 "Unexpected value for dss precedence");
519 TEST_BEGIN(test_arenas_initialized
)
522 size_t sz
= sizeof(narenas
);
524 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas
, &sz
, NULL
, 0),
525 0, "Unexpected mallctl() failure");
527 VARIABLE_ARRAY(bool, initialized
, narenas
);
529 sz
= narenas
* sizeof(bool);
530 assert_d_eq(mallctl("arenas.initialized", (void *)initialized
,
531 &sz
, NULL
, 0), 0, "Unexpected mallctl() failure");
536 TEST_BEGIN(test_arenas_lg_dirty_mult
)
538 ssize_t lg_dirty_mult
, orig_lg_dirty_mult
, prev_lg_dirty_mult
;
539 size_t sz
= sizeof(ssize_t
);
541 test_skip_if(opt_purge
!= purge_mode_ratio
);
543 assert_d_eq(mallctl("arenas.lg_dirty_mult", (void *)&orig_lg_dirty_mult
,
544 &sz
, NULL
, 0), 0, "Unexpected mallctl() failure");
547 assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL
, NULL
,
548 (void *)&lg_dirty_mult
, sizeof(ssize_t
)), EFAULT
,
549 "Unexpected mallctl() success");
551 lg_dirty_mult
= (sizeof(size_t) << 3);
552 assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL
, NULL
,
553 (void *)&lg_dirty_mult
, sizeof(ssize_t
)), EFAULT
,
554 "Unexpected mallctl() success");
556 for (prev_lg_dirty_mult
= orig_lg_dirty_mult
, lg_dirty_mult
= -1;
557 lg_dirty_mult
< (ssize_t
)(sizeof(size_t) << 3); prev_lg_dirty_mult
=
558 lg_dirty_mult
, lg_dirty_mult
++) {
559 ssize_t old_lg_dirty_mult
;
561 assert_d_eq(mallctl("arenas.lg_dirty_mult",
562 (void *)&old_lg_dirty_mult
, &sz
, (void *)&lg_dirty_mult
,
563 sizeof(ssize_t
)), 0, "Unexpected mallctl() failure");
564 assert_zd_eq(old_lg_dirty_mult
, prev_lg_dirty_mult
,
565 "Unexpected old arenas.lg_dirty_mult");
570 TEST_BEGIN(test_arenas_decay_time
)
572 ssize_t decay_time
, orig_decay_time
, prev_decay_time
;
573 size_t sz
= sizeof(ssize_t
);
575 test_skip_if(opt_purge
!= purge_mode_decay
);
577 assert_d_eq(mallctl("arenas.decay_time", (void *)&orig_decay_time
, &sz
,
578 NULL
, 0), 0, "Unexpected mallctl() failure");
581 assert_d_eq(mallctl("arenas.decay_time", NULL
, NULL
,
582 (void *)&decay_time
, sizeof(ssize_t
)), EFAULT
,
583 "Unexpected mallctl() success");
585 decay_time
= 0x7fffffff;
586 assert_d_eq(mallctl("arenas.decay_time", NULL
, NULL
,
587 (void *)&decay_time
, sizeof(ssize_t
)), 0,
588 "Expected mallctl() failure");
590 for (prev_decay_time
= decay_time
, decay_time
= -1;
591 decay_time
< 20; prev_decay_time
= decay_time
, decay_time
++) {
592 ssize_t old_decay_time
;
594 assert_d_eq(mallctl("arenas.decay_time",
595 (void *)&old_decay_time
, &sz
, (void *)&decay_time
,
596 sizeof(ssize_t
)), 0, "Unexpected mallctl() failure");
597 assert_zd_eq(old_decay_time
, prev_decay_time
,
598 "Unexpected old arenas.decay_time");
603 TEST_BEGIN(test_arenas_constants
)
606 #define TEST_ARENAS_CONSTANT(t, name, expected) do { \
608 size_t sz = sizeof(t); \
609 assert_d_eq(mallctl("arenas."#name, (void *)&name, &sz, NULL, \
610 0), 0, "Unexpected mallctl() failure"); \
611 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
614 TEST_ARENAS_CONSTANT(size_t, quantum
, QUANTUM
);
615 TEST_ARENAS_CONSTANT(size_t, page
, PAGE
);
616 TEST_ARENAS_CONSTANT(unsigned, nbins
, NBINS
);
617 TEST_ARENAS_CONSTANT(unsigned, nlruns
, nlclasses
);
618 TEST_ARENAS_CONSTANT(unsigned, nhchunks
, nhclasses
);
620 #undef TEST_ARENAS_CONSTANT
624 TEST_BEGIN(test_arenas_bin_constants
)
627 #define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \
629 size_t sz = sizeof(t); \
630 assert_d_eq(mallctl("arenas.bin.0."#name, (void *)&name, &sz, \
631 NULL, 0), 0, "Unexpected mallctl() failure"); \
632 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
635 TEST_ARENAS_BIN_CONSTANT(size_t, size
, arena_bin_info
[0].reg_size
);
636 TEST_ARENAS_BIN_CONSTANT(uint32_t, nregs
, arena_bin_info
[0].nregs
);
637 TEST_ARENAS_BIN_CONSTANT(size_t, run_size
, arena_bin_info
[0].run_size
);
639 #undef TEST_ARENAS_BIN_CONSTANT
643 TEST_BEGIN(test_arenas_lrun_constants
)
646 #define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \
648 size_t sz = sizeof(t); \
649 assert_d_eq(mallctl("arenas.lrun.0."#name, (void *)&name, &sz, \
650 NULL, 0), 0, "Unexpected mallctl() failure"); \
651 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
654 TEST_ARENAS_LRUN_CONSTANT(size_t, size
, LARGE_MINCLASS
);
656 #undef TEST_ARENAS_LRUN_CONSTANT
660 TEST_BEGIN(test_arenas_hchunk_constants
)
663 #define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \
665 size_t sz = sizeof(t); \
666 assert_d_eq(mallctl("arenas.hchunk.0."#name, (void *)&name, \
667 &sz, NULL, 0), 0, "Unexpected mallctl() failure"); \
668 assert_zu_eq(name, expected, "Incorrect "#name" size"); \
671 TEST_ARENAS_HCHUNK_CONSTANT(size_t, size
, chunksize
);
673 #undef TEST_ARENAS_HCHUNK_CONSTANT
677 TEST_BEGIN(test_arenas_extend
)
679 unsigned narenas_before
, arena
, narenas_after
;
680 size_t sz
= sizeof(unsigned);
682 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_before
, &sz
,
683 NULL
, 0), 0, "Unexpected mallctl() failure");
684 assert_d_eq(mallctl("arenas.extend", (void *)&arena
, &sz
, NULL
, 0), 0,
685 "Unexpected mallctl() failure");
686 assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_after
, &sz
, NULL
,
687 0), 0, "Unexpected mallctl() failure");
689 assert_u_eq(narenas_before
+1, narenas_after
,
690 "Unexpected number of arenas before versus after extension");
691 assert_u_eq(arena
, narenas_after
-1, "Unexpected arena index");
695 TEST_BEGIN(test_stats_arenas
)
698 #define TEST_STATS_ARENAS(t, name) do { \
700 size_t sz = sizeof(t); \
701 assert_d_eq(mallctl("stats.arenas.0."#name, (void *)&name, &sz, \
702 NULL, 0), 0, "Unexpected mallctl() failure"); \
705 TEST_STATS_ARENAS(unsigned, nthreads
);
706 TEST_STATS_ARENAS(const char *, dss
);
707 TEST_STATS_ARENAS(ssize_t
, lg_dirty_mult
);
708 TEST_STATS_ARENAS(ssize_t
, decay_time
);
709 TEST_STATS_ARENAS(size_t, pactive
);
710 TEST_STATS_ARENAS(size_t, pdirty
);
712 #undef TEST_STATS_ARENAS
722 test_mallctlnametomib_errors
,
723 test_mallctlbymib_errors
,
724 test_mallctl_read_write
,
725 test_mallctlnametomib_short_mib
,
728 test_manpage_example
,
732 test_arena_i_lg_dirty_mult
,
733 test_arena_i_decay_time
,
737 test_arenas_initialized
,
738 test_arenas_lg_dirty_mult
,
739 test_arenas_decay_time
,
740 test_arenas_constants
,
741 test_arenas_bin_constants
,
742 test_arenas_lrun_constants
,
743 test_arenas_hchunk_constants
,