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