1 #include "test/jemalloc_test.h"
2
TEST_BEGIN(test_stats_summary)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
TEST_BEGIN(test_stats_huge)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
TEST_BEGIN(test_stats_arenas_summary)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 *
thd_start(void * arg)127 thd_start(void *arg)
128 {
129
130 return (NULL);
131 }
132
133 static void
no_lazy_lock(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
TEST_BEGIN(test_stats_arenas_small)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
TEST_BEGIN(test_stats_arenas_large)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
TEST_BEGIN(test_stats_arenas_huge)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
TEST_BEGIN(test_stats_arenas_bins)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
TEST_BEGIN(test_stats_arenas_lruns)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
TEST_BEGIN(test_stats_arenas_hchunks)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
main(void)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