1 #include "test/jemalloc_test.h"
2
TEST_BEGIN(test_small_run_size)3 TEST_BEGIN(test_small_run_size)
4 {
5 unsigned nbins, i;
6 size_t sz, run_size;
7 size_t mib[4];
8 size_t miblen = sizeof(mib) / sizeof(size_t);
9
10 /*
11 * Iterate over all small size classes, get their run sizes, and verify
12 * that the quantized size is the same as the run size.
13 */
14
15 sz = sizeof(unsigned);
16 assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
17 "Unexpected mallctl failure");
18
19 assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
20 "Unexpected mallctlnametomib failure");
21 for (i = 0; i < nbins; i++) {
22 mib[2] = i;
23 sz = sizeof(size_t);
24 assert_d_eq(mallctlbymib(mib, miblen, (void *)&run_size, &sz,
25 NULL, 0), 0, "Unexpected mallctlbymib failure");
26 assert_zu_eq(run_size, run_quantize_floor(run_size),
27 "Small run quantization should be a no-op (run_size=%zu)",
28 run_size);
29 assert_zu_eq(run_size, run_quantize_ceil(run_size),
30 "Small run quantization should be a no-op (run_size=%zu)",
31 run_size);
32 }
33 }
34 TEST_END
35
TEST_BEGIN(test_large_run_size)36 TEST_BEGIN(test_large_run_size)
37 {
38 bool cache_oblivious;
39 unsigned nlruns, i;
40 size_t sz, run_size_prev, ceil_prev;
41 size_t mib[4];
42 size_t miblen = sizeof(mib) / sizeof(size_t);
43
44 /*
45 * Iterate over all large size classes, get their run sizes, and verify
46 * that the quantized size is the same as the run size.
47 */
48
49 sz = sizeof(bool);
50 assert_d_eq(mallctl("config.cache_oblivious", (void *)&cache_oblivious,
51 &sz, NULL, 0), 0, "Unexpected mallctl failure");
52
53 sz = sizeof(unsigned);
54 assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
55 "Unexpected mallctl failure");
56
57 assert_d_eq(mallctlnametomib("arenas.lrun.0.size", mib, &miblen), 0,
58 "Unexpected mallctlnametomib failure");
59 for (i = 0; i < nlruns; i++) {
60 size_t lrun_size, run_size, floor, ceil;
61
62 mib[2] = i;
63 sz = sizeof(size_t);
64 assert_d_eq(mallctlbymib(mib, miblen, (void *)&lrun_size, &sz,
65 NULL, 0), 0, "Unexpected mallctlbymib failure");
66 run_size = cache_oblivious ? lrun_size + PAGE : lrun_size;
67 floor = run_quantize_floor(run_size);
68 ceil = run_quantize_ceil(run_size);
69
70 assert_zu_eq(run_size, floor,
71 "Large run quantization should be a no-op for precise "
72 "size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
73 assert_zu_eq(run_size, ceil,
74 "Large run quantization should be a no-op for precise "
75 "size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
76
77 if (i > 0) {
78 assert_zu_eq(run_size_prev, run_quantize_floor(run_size
79 - PAGE), "Floor should be a precise size");
80 if (run_size_prev < ceil_prev) {
81 assert_zu_eq(ceil_prev, run_size,
82 "Ceiling should be a precise size "
83 "(run_size_prev=%zu, ceil_prev=%zu, "
84 "run_size=%zu)", run_size_prev, ceil_prev,
85 run_size);
86 }
87 }
88 run_size_prev = floor;
89 ceil_prev = run_quantize_ceil(run_size + PAGE);
90 }
91 }
92 TEST_END
93
TEST_BEGIN(test_monotonic)94 TEST_BEGIN(test_monotonic)
95 {
96 unsigned nbins, nlruns, i;
97 size_t sz, floor_prev, ceil_prev;
98
99 /*
100 * Iterate over all run sizes and verify that
101 * run_quantize_{floor,ceil}() are monotonic.
102 */
103
104 sz = sizeof(unsigned);
105 assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
106 "Unexpected mallctl failure");
107
108 sz = sizeof(unsigned);
109 assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
110 "Unexpected mallctl failure");
111
112 floor_prev = 0;
113 ceil_prev = 0;
114 for (i = 1; i <= chunksize >> LG_PAGE; i++) {
115 size_t run_size, floor, ceil;
116
117 run_size = i << LG_PAGE;
118 floor = run_quantize_floor(run_size);
119 ceil = run_quantize_ceil(run_size);
120
121 assert_zu_le(floor, run_size,
122 "Floor should be <= (floor=%zu, run_size=%zu, ceil=%zu)",
123 floor, run_size, ceil);
124 assert_zu_ge(ceil, run_size,
125 "Ceiling should be >= (floor=%zu, run_size=%zu, ceil=%zu)",
126 floor, run_size, ceil);
127
128 assert_zu_le(floor_prev, floor, "Floor should be monotonic "
129 "(floor_prev=%zu, floor=%zu, run_size=%zu, ceil=%zu)",
130 floor_prev, floor, run_size, ceil);
131 assert_zu_le(ceil_prev, ceil, "Ceiling should be monotonic "
132 "(floor=%zu, run_size=%zu, ceil_prev=%zu, ceil=%zu)",
133 floor, run_size, ceil_prev, ceil);
134
135 floor_prev = floor;
136 ceil_prev = ceil;
137 }
138 }
139 TEST_END
140
141 int
main(void)142 main(void)
143 {
144
145 return (test(
146 test_small_run_size,
147 test_large_run_size,
148 test_monotonic));
149 }
150