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