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