Home | History | Annotate | Download | only in unit
      1 #include "test/jemalloc_test.h"
      2 
      3 TEST_BEGIN(test_stats_summary)
      4 {
      5 	size_t *cactive;
      6 	size_t sz, allocated, active, resident, mapped;
      7 	int expected = config_stats ? 0 : ENOENT;
      8 
      9 	sz = sizeof(cactive);
     10 	assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected,
     11 	    "Unexpected mallctl() result");
     12 
     13 	sz = sizeof(size_t);
     14 	assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
     15 	    expected, "Unexpected mallctl() result");
     16 	assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected,
     17 	    "Unexpected mallctl() result");
     18 	assert_d_eq(mallctl("stats.resident", &resident, &sz, NULL, 0),
     19 	    expected, "Unexpected mallctl() result");
     20 	assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
     21 	    "Unexpected mallctl() result");
     22 
     23 	if (config_stats) {
     24 		assert_zu_le(active, *cactive,
     25 		    "active should be no larger than cactive");
     26 		assert_zu_le(allocated, active,
     27 		    "allocated should be no larger than active");
     28 		assert_zu_lt(active, resident,
     29 		    "active should be less than resident");
     30 		assert_zu_lt(active, mapped,
     31 		    "active should be less than mapped");
     32 	}
     33 }
     34 TEST_END
     35 
     36 TEST_BEGIN(test_stats_huge)
     37 {
     38 	void *p;
     39 	uint64_t epoch;
     40 	size_t allocated;
     41 	uint64_t nmalloc, ndalloc, nrequests;
     42 	size_t sz;
     43 	int expected = config_stats ? 0 : ENOENT;
     44 
     45 	p = mallocx(large_maxclass+1, 0);
     46 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
     47 
     48 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
     49 	    "Unexpected mallctl() failure");
     50 
     51 	sz = sizeof(size_t);
     52 	assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
     53 	    NULL, 0), expected, "Unexpected mallctl() result");
     54 	sz = sizeof(uint64_t);
     55 	assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, NULL,
     56 	    0), expected, "Unexpected mallctl() result");
     57 	assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, NULL,
     58 	    0), expected, "Unexpected mallctl() result");
     59 	assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", &nrequests, &sz,
     60 	    NULL, 0), expected, "Unexpected mallctl() result");
     61 
     62 	if (config_stats) {
     63 		assert_zu_gt(allocated, 0,
     64 		    "allocated should be greater than zero");
     65 		assert_u64_ge(nmalloc, ndalloc,
     66 		    "nmalloc should be at least as large as ndalloc");
     67 		assert_u64_le(nmalloc, nrequests,
     68 		    "nmalloc should no larger than nrequests");
     69 	}
     70 
     71 	dallocx(p, 0);
     72 }
     73 TEST_END
     74 
     75 TEST_BEGIN(test_stats_arenas_summary)
     76 {
     77 	unsigned arena;
     78 	void *little, *large, *huge;
     79 	uint64_t epoch;
     80 	size_t sz;
     81 	int expected = config_stats ? 0 : ENOENT;
     82 	size_t mapped;
     83 	uint64_t npurge, nmadvise, purged;
     84 
     85 	arena = 0;
     86 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
     87 	    0, "Unexpected mallctl() failure");
     88 
     89 	little = mallocx(SMALL_MAXCLASS, 0);
     90 	assert_ptr_not_null(little, "Unexpected mallocx() failure");
     91 	large = mallocx(large_maxclass, 0);
     92 	assert_ptr_not_null(large, "Unexpected mallocx() failure");
     93 	huge = mallocx(chunksize, 0);
     94 	assert_ptr_not_null(huge, "Unexpected mallocx() failure");
     95 
     96 	dallocx(little, 0);
     97 	dallocx(large, 0);
     98 	dallocx(huge, 0);
     99 
    100 	assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
    101 	    "Unexpected mallctl() failure");
    102 
    103 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    104 	    "Unexpected mallctl() failure");
    105 
    106 	sz = sizeof(size_t);
    107 	assert_d_eq(mallctl("stats.arenas.0.mapped", &mapped, &sz, NULL, 0),
    108 	    expected, "Unexepected mallctl() result");
    109 	sz = sizeof(uint64_t);
    110 	assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge, &sz, NULL, 0),
    111 	    expected, "Unexepected mallctl() result");
    112 	assert_d_eq(mallctl("stats.arenas.0.nmadvise", &nmadvise, &sz, NULL, 0),
    113 	    expected, "Unexepected mallctl() result");
    114 	assert_d_eq(mallctl("stats.arenas.0.purged", &purged, &sz, NULL, 0),
    115 	    expected, "Unexepected mallctl() result");
    116 
    117 	if (config_stats) {
    118 		assert_u64_gt(npurge, 0,
    119 		    "At least one purge should have occurred");
    120 		assert_u64_le(nmadvise, purged,
    121 		    "nmadvise should be no greater than purged");
    122 	}
    123 }
    124 TEST_END
    125 
    126 void *
    127 thd_start(void *arg)
    128 {
    129 
    130 	return (NULL);
    131 }
    132 
    133 static void
    134 no_lazy_lock(void)
    135 {
    136 	thd_t thd;
    137 
    138 	thd_create(&thd, thd_start, NULL);
    139 	thd_join(thd, NULL);
    140 }
    141 
    142 TEST_BEGIN(test_stats_arenas_small)
    143 {
    144 	unsigned arena;
    145 	void *p;
    146 	size_t sz, allocated;
    147 	uint64_t epoch, nmalloc, ndalloc, nrequests;
    148 	int expected = config_stats ? 0 : ENOENT;
    149 
    150 	no_lazy_lock(); /* Lazy locking would dodge tcache testing. */
    151 
    152 	arena = 0;
    153 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    154 	    0, "Unexpected mallctl() failure");
    155 
    156 	p = mallocx(SMALL_MAXCLASS, 0);
    157 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    158 
    159 	assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
    160 	    config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
    161 
    162 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    163 	    "Unexpected mallctl() failure");
    164 
    165 	sz = sizeof(size_t);
    166 	assert_d_eq(mallctl("stats.arenas.0.small.allocated", &allocated, &sz,
    167 	    NULL, 0), expected, "Unexpected mallctl() result");
    168 	sz = sizeof(uint64_t);
    169 	assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", &nmalloc, &sz,
    170 	    NULL, 0), expected, "Unexpected mallctl() result");
    171 	assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", &ndalloc, &sz,
    172 	    NULL, 0), expected, "Unexpected mallctl() result");
    173 	assert_d_eq(mallctl("stats.arenas.0.small.nrequests", &nrequests, &sz,
    174 	    NULL, 0), expected, "Unexpected mallctl() result");
    175 
    176 	if (config_stats) {
    177 		assert_zu_gt(allocated, 0,
    178 		    "allocated should be greater than zero");
    179 		assert_u64_gt(nmalloc, 0,
    180 		    "nmalloc should be no greater than zero");
    181 		assert_u64_ge(nmalloc, ndalloc,
    182 		    "nmalloc should be at least as large as ndalloc");
    183 		assert_u64_gt(nrequests, 0,
    184 		    "nrequests should be greater than zero");
    185 	}
    186 
    187 	dallocx(p, 0);
    188 }
    189 TEST_END
    190 
    191 TEST_BEGIN(test_stats_arenas_large)
    192 {
    193 	unsigned arena;
    194 	void *p;
    195 	size_t sz, allocated;
    196 	uint64_t epoch, nmalloc, ndalloc, nrequests;
    197 	int expected = config_stats ? 0 : ENOENT;
    198 
    199 	arena = 0;
    200 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    201 	    0, "Unexpected mallctl() failure");
    202 
    203 	p = mallocx(large_maxclass, 0);
    204 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    205 
    206 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    207 	    "Unexpected mallctl() failure");
    208 
    209 	sz = sizeof(size_t);
    210 	assert_d_eq(mallctl("stats.arenas.0.large.allocated", &allocated, &sz,
    211 	    NULL, 0), expected, "Unexpected mallctl() result");
    212 	sz = sizeof(uint64_t);
    213 	assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", &nmalloc, &sz,
    214 	    NULL, 0), expected, "Unexpected mallctl() result");
    215 	assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", &ndalloc, &sz,
    216 	    NULL, 0), expected, "Unexpected mallctl() result");
    217 	assert_d_eq(mallctl("stats.arenas.0.large.nrequests", &nrequests, &sz,
    218 	    NULL, 0), expected, "Unexpected mallctl() result");
    219 
    220 	if (config_stats) {
    221 		assert_zu_gt(allocated, 0,
    222 		    "allocated should be greater than zero");
    223 		assert_zu_gt(nmalloc, 0,
    224 		    "nmalloc should be greater than zero");
    225 		assert_zu_ge(nmalloc, ndalloc,
    226 		    "nmalloc should be at least as large as ndalloc");
    227 		assert_zu_gt(nrequests, 0,
    228 		    "nrequests should be greater than zero");
    229 	}
    230 
    231 	dallocx(p, 0);
    232 }
    233 TEST_END
    234 
    235 TEST_BEGIN(test_stats_arenas_huge)
    236 {
    237 	unsigned arena;
    238 	void *p;
    239 	size_t sz, allocated;
    240 	uint64_t epoch, nmalloc, ndalloc;
    241 	int expected = config_stats ? 0 : ENOENT;
    242 
    243 	arena = 0;
    244 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    245 	    0, "Unexpected mallctl() failure");
    246 
    247 	p = mallocx(chunksize, 0);
    248 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    249 
    250 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    251 	    "Unexpected mallctl() failure");
    252 
    253 	sz = sizeof(size_t);
    254 	assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz,
    255 	    NULL, 0), expected, "Unexpected mallctl() result");
    256 	sz = sizeof(uint64_t);
    257 	assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz,
    258 	    NULL, 0), expected, "Unexpected mallctl() result");
    259 	assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz,
    260 	    NULL, 0), expected, "Unexpected mallctl() result");
    261 
    262 	if (config_stats) {
    263 		assert_zu_gt(allocated, 0,
    264 		    "allocated should be greater than zero");
    265 		assert_zu_gt(nmalloc, 0,
    266 		    "nmalloc should be greater than zero");
    267 		assert_zu_ge(nmalloc, ndalloc,
    268 		    "nmalloc should be at least as large as ndalloc");
    269 	}
    270 
    271 	dallocx(p, 0);
    272 }
    273 TEST_END
    274 
    275 TEST_BEGIN(test_stats_arenas_bins)
    276 {
    277 	unsigned arena;
    278 	void *p;
    279 	size_t sz, curruns, curregs;
    280 	uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes;
    281 	uint64_t nruns, nreruns;
    282 	int expected = config_stats ? 0 : ENOENT;
    283 
    284 	arena = 0;
    285 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    286 	    0, "Unexpected mallctl() failure");
    287 
    288 	p = mallocx(arena_bin_info[0].reg_size, 0);
    289 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    290 
    291 	assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0),
    292 	    config_tcache ? 0 : ENOENT, "Unexpected mallctl() result");
    293 
    294 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    295 	    "Unexpected mallctl() failure");
    296 
    297 	sz = sizeof(uint64_t);
    298 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz,
    299 	    NULL, 0), expected, "Unexpected mallctl() result");
    300 	assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", &ndalloc, &sz,
    301 	    NULL, 0), expected, "Unexpected mallctl() result");
    302 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz,
    303 	    NULL, 0), expected, "Unexpected mallctl() result");
    304 	sz = sizeof(size_t);
    305 	assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", &curregs, &sz,
    306 	    NULL, 0), expected, "Unexpected mallctl() result");
    307 
    308 	sz = sizeof(uint64_t);
    309 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
    310 	    NULL, 0), config_tcache ? expected : ENOENT,
    311 	    "Unexpected mallctl() result");
    312 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz,
    313 	    NULL, 0), config_tcache ? expected : ENOENT,
    314 	    "Unexpected mallctl() result");
    315 
    316 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", &nruns, &sz,
    317 	    NULL, 0), expected, "Unexpected mallctl() result");
    318 	assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", &nreruns, &sz,
    319 	    NULL, 0), expected, "Unexpected mallctl() result");
    320 	sz = sizeof(size_t);
    321 	assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", &curruns, &sz,
    322 	    NULL, 0), expected, "Unexpected mallctl() result");
    323 
    324 	if (config_stats) {
    325 		assert_u64_gt(nmalloc, 0,
    326 		    "nmalloc should be greater than zero");
    327 		assert_u64_ge(nmalloc, ndalloc,
    328 		    "nmalloc should be at least as large as ndalloc");
    329 		assert_u64_gt(nrequests, 0,
    330 		    "nrequests should be greater than zero");
    331 		assert_zu_gt(curregs, 0,
    332 		    "allocated should be greater than zero");
    333 		if (config_tcache) {
    334 			assert_u64_gt(nfills, 0,
    335 			    "At least one fill should have occurred");
    336 			assert_u64_gt(nflushes, 0,
    337 			    "At least one flush should have occurred");
    338 		}
    339 		assert_u64_gt(nruns, 0,
    340 		    "At least one run should have been allocated");
    341 		assert_zu_gt(curruns, 0,
    342 		    "At least one run should be currently allocated");
    343 	}
    344 
    345 	dallocx(p, 0);
    346 }
    347 TEST_END
    348 
    349 TEST_BEGIN(test_stats_arenas_lruns)
    350 {
    351 	unsigned arena;
    352 	void *p;
    353 	uint64_t epoch, nmalloc, ndalloc, nrequests;
    354 	size_t curruns, sz;
    355 	int expected = config_stats ? 0 : ENOENT;
    356 
    357 	arena = 0;
    358 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    359 	    0, "Unexpected mallctl() failure");
    360 
    361 	p = mallocx(LARGE_MINCLASS, 0);
    362 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    363 
    364 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    365 	    "Unexpected mallctl() failure");
    366 
    367 	sz = sizeof(uint64_t);
    368 	assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", &nmalloc, &sz,
    369 	    NULL, 0), expected, "Unexpected mallctl() result");
    370 	assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", &ndalloc, &sz,
    371 	    NULL, 0), expected, "Unexpected mallctl() result");
    372 	assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests", &nrequests, &sz,
    373 	    NULL, 0), expected, "Unexpected mallctl() result");
    374 	sz = sizeof(size_t);
    375 	assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", &curruns, &sz,
    376 	    NULL, 0), expected, "Unexpected mallctl() result");
    377 
    378 	if (config_stats) {
    379 		assert_u64_gt(nmalloc, 0,
    380 		    "nmalloc should be greater than zero");
    381 		assert_u64_ge(nmalloc, ndalloc,
    382 		    "nmalloc should be at least as large as ndalloc");
    383 		assert_u64_gt(nrequests, 0,
    384 		    "nrequests should be greater than zero");
    385 		assert_u64_gt(curruns, 0,
    386 		    "At least one run should be currently allocated");
    387 	}
    388 
    389 	dallocx(p, 0);
    390 }
    391 TEST_END
    392 
    393 TEST_BEGIN(test_stats_arenas_hchunks)
    394 {
    395 	unsigned arena;
    396 	void *p;
    397 	uint64_t epoch, nmalloc, ndalloc;
    398 	size_t curhchunks, sz;
    399 	int expected = config_stats ? 0 : ENOENT;
    400 
    401 	arena = 0;
    402 	assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)),
    403 	    0, "Unexpected mallctl() failure");
    404 
    405 	p = mallocx(chunksize, 0);
    406 	assert_ptr_not_null(p, "Unexpected mallocx() failure");
    407 
    408 	assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0,
    409 	    "Unexpected mallctl() failure");
    410 
    411 	sz = sizeof(uint64_t);
    412 	assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc", &nmalloc, &sz,
    413 	    NULL, 0), expected, "Unexpected mallctl() result");
    414 	assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc", &ndalloc, &sz,
    415 	    NULL, 0), expected, "Unexpected mallctl() result");
    416 	sz = sizeof(size_t);
    417 	assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks", &curhchunks,
    418 	    &sz, NULL, 0), expected, "Unexpected mallctl() result");
    419 
    420 	if (config_stats) {
    421 		assert_u64_gt(nmalloc, 0,
    422 		    "nmalloc should be greater than zero");
    423 		assert_u64_ge(nmalloc, ndalloc,
    424 		    "nmalloc should be at least as large as ndalloc");
    425 		assert_u64_gt(curhchunks, 0,
    426 		    "At least one chunk should be currently allocated");
    427 	}
    428 
    429 	dallocx(p, 0);
    430 }
    431 TEST_END
    432 
    433 int
    434 main(void)
    435 {
    436 
    437 	return (test(
    438 	    test_stats_summary,
    439 	    test_stats_huge,
    440 	    test_stats_arenas_summary,
    441 	    test_stats_arenas_small,
    442 	    test_stats_arenas_large,
    443 	    test_stats_arenas_huge,
    444 	    test_stats_arenas_bins,
    445 	    test_stats_arenas_lruns,
    446 	    test_stats_arenas_hchunks));
    447 }
    448