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", &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, &run_size, &sz, NULL, 0),
25 		    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", &cache_oblivious, &sz,
51 	    NULL, 0), 0, "Unexpected mallctl failure");
52 
53 	sz = sizeof(unsigned);
54 	assert_d_eq(mallctl("arenas.nlruns", &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, &lrun_size, &sz, NULL, 0),
65 		    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", &nbins, &sz, NULL, 0), 0,
106 	    "Unexpected mallctl failure");
107 
108 	sz = sizeof(unsigned);
109 	assert_d_eq(mallctl("arenas.nlruns", &nlruns, &sz, NULL, 0), 0,
110 	    "Unexpected mallctl failure");
111 
112 	floor_prev = 0;
113 	ceil_prev = 0;
114 	for (i = 1; i < run_quantize_max >> 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