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