xref: /netbsd-src/external/bsd/jemalloc/dist/test/unit/extent_quantize.c (revision 7bdf38e5b7a28439665f2fdeff81e36913eef7dd)
1a0698ed9Schristos #include "test/jemalloc_test.h"
2a0698ed9Schristos 
3a0698ed9Schristos TEST_BEGIN(test_small_extent_size) {
4a0698ed9Schristos 	unsigned nbins, i;
5a0698ed9Schristos 	size_t sz, extent_size;
6a0698ed9Schristos 	size_t mib[4];
7a0698ed9Schristos 	size_t miblen = sizeof(mib) / sizeof(size_t);
8a0698ed9Schristos 
9a0698ed9Schristos 	/*
10a0698ed9Schristos 	 * Iterate over all small size classes, get their extent sizes, and
11a0698ed9Schristos 	 * verify that the quantized size is the same as the extent size.
12a0698ed9Schristos 	 */
13a0698ed9Schristos 
14a0698ed9Schristos 	sz = sizeof(unsigned);
15*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
16a0698ed9Schristos 	    "Unexpected mallctl failure");
17a0698ed9Schristos 
18*7bdf38e5Schristos 	expect_d_eq(mallctlnametomib("arenas.bin.0.slab_size", mib, &miblen), 0,
19a0698ed9Schristos 	    "Unexpected mallctlnametomib failure");
20a0698ed9Schristos 	for (i = 0; i < nbins; i++) {
21a0698ed9Schristos 		mib[2] = i;
22a0698ed9Schristos 		sz = sizeof(size_t);
23*7bdf38e5Schristos 		expect_d_eq(mallctlbymib(mib, miblen, (void *)&extent_size, &sz,
24a0698ed9Schristos 		    NULL, 0), 0, "Unexpected mallctlbymib failure");
25*7bdf38e5Schristos 		expect_zu_eq(extent_size,
26*7bdf38e5Schristos 		    sz_psz_quantize_floor(extent_size),
27a0698ed9Schristos 		    "Small extent quantization should be a no-op "
28a0698ed9Schristos 		    "(extent_size=%zu)", extent_size);
29*7bdf38e5Schristos 		expect_zu_eq(extent_size,
30*7bdf38e5Schristos 		    sz_psz_quantize_ceil(extent_size),
31a0698ed9Schristos 		    "Small extent quantization should be a no-op "
32a0698ed9Schristos 		    "(extent_size=%zu)", extent_size);
33a0698ed9Schristos 	}
34a0698ed9Schristos }
35a0698ed9Schristos TEST_END
36a0698ed9Schristos 
37a0698ed9Schristos TEST_BEGIN(test_large_extent_size) {
38a0698ed9Schristos 	bool cache_oblivious;
39a0698ed9Schristos 	unsigned nlextents, i;
40a0698ed9Schristos 	size_t sz, extent_size_prev, ceil_prev;
41a0698ed9Schristos 	size_t mib[4];
42a0698ed9Schristos 	size_t miblen = sizeof(mib) / sizeof(size_t);
43a0698ed9Schristos 
44a0698ed9Schristos 	/*
45a0698ed9Schristos 	 * Iterate over all large size classes, get their extent sizes, and
46a0698ed9Schristos 	 * verify that the quantized size is the same as the extent size.
47a0698ed9Schristos 	 */
48a0698ed9Schristos 
49a0698ed9Schristos 	sz = sizeof(bool);
50*7bdf38e5Schristos 	expect_d_eq(mallctl("opt.cache_oblivious", (void *)&cache_oblivious,
51a0698ed9Schristos 	    &sz, NULL, 0), 0, "Unexpected mallctl failure");
52a0698ed9Schristos 
53a0698ed9Schristos 	sz = sizeof(unsigned);
54*7bdf38e5Schristos 	expect_d_eq(mallctl("arenas.nlextents", (void *)&nlextents, &sz, NULL,
55a0698ed9Schristos 	    0), 0, "Unexpected mallctl failure");
56a0698ed9Schristos 
57*7bdf38e5Schristos 	expect_d_eq(mallctlnametomib("arenas.lextent.0.size", mib, &miblen), 0,
58a0698ed9Schristos 	    "Unexpected mallctlnametomib failure");
59a0698ed9Schristos 	for (i = 0; i < nlextents; i++) {
60a0698ed9Schristos 		size_t lextent_size, extent_size, floor, ceil;
61a0698ed9Schristos 
62a0698ed9Schristos 		mib[2] = i;
63a0698ed9Schristos 		sz = sizeof(size_t);
64*7bdf38e5Schristos 		expect_d_eq(mallctlbymib(mib, miblen, (void *)&lextent_size,
65a0698ed9Schristos 		    &sz, NULL, 0), 0, "Unexpected mallctlbymib failure");
66a0698ed9Schristos 		extent_size = cache_oblivious ? lextent_size + PAGE :
67a0698ed9Schristos 		    lextent_size;
68*7bdf38e5Schristos 		floor = sz_psz_quantize_floor(extent_size);
69*7bdf38e5Schristos 		ceil = sz_psz_quantize_ceil(extent_size);
70a0698ed9Schristos 
71*7bdf38e5Schristos 		expect_zu_eq(extent_size, floor,
72a0698ed9Schristos 		    "Extent quantization should be a no-op for precise size "
73a0698ed9Schristos 		    "(lextent_size=%zu, extent_size=%zu)", lextent_size,
74a0698ed9Schristos 		    extent_size);
75*7bdf38e5Schristos 		expect_zu_eq(extent_size, ceil,
76a0698ed9Schristos 		    "Extent quantization should be a no-op for precise size "
77a0698ed9Schristos 		    "(lextent_size=%zu, extent_size=%zu)", lextent_size,
78a0698ed9Schristos 		    extent_size);
79a0698ed9Schristos 
80a0698ed9Schristos 		if (i > 0) {
81*7bdf38e5Schristos 			expect_zu_eq(extent_size_prev,
82*7bdf38e5Schristos 			    sz_psz_quantize_floor(extent_size - PAGE),
83a0698ed9Schristos 			    "Floor should be a precise size");
84a0698ed9Schristos 			if (extent_size_prev < ceil_prev) {
85*7bdf38e5Schristos 				expect_zu_eq(ceil_prev, extent_size,
86a0698ed9Schristos 				    "Ceiling should be a precise size "
87a0698ed9Schristos 				    "(extent_size_prev=%zu, ceil_prev=%zu, "
88a0698ed9Schristos 				    "extent_size=%zu)", extent_size_prev,
89a0698ed9Schristos 				    ceil_prev, extent_size);
90a0698ed9Schristos 			}
91a0698ed9Schristos 		}
92a0698ed9Schristos 		if (i + 1 < nlextents) {
93a0698ed9Schristos 			extent_size_prev = floor;
94*7bdf38e5Schristos 			ceil_prev = sz_psz_quantize_ceil(extent_size +
95a0698ed9Schristos 			    PAGE);
96a0698ed9Schristos 		}
97a0698ed9Schristos 	}
98a0698ed9Schristos }
99a0698ed9Schristos TEST_END
100a0698ed9Schristos 
101a0698ed9Schristos TEST_BEGIN(test_monotonic) {
102a0698ed9Schristos #define SZ_MAX	ZU(4 * 1024 * 1024)
103a0698ed9Schristos 	unsigned i;
104a0698ed9Schristos 	size_t floor_prev, ceil_prev;
105a0698ed9Schristos 
106a0698ed9Schristos 	floor_prev = 0;
107a0698ed9Schristos 	ceil_prev = 0;
108a0698ed9Schristos 	for (i = 1; i <= SZ_MAX >> LG_PAGE; i++) {
109a0698ed9Schristos 		size_t extent_size, floor, ceil;
110a0698ed9Schristos 
111a0698ed9Schristos 		extent_size = i << LG_PAGE;
112*7bdf38e5Schristos 		floor = sz_psz_quantize_floor(extent_size);
113*7bdf38e5Schristos 		ceil = sz_psz_quantize_ceil(extent_size);
114a0698ed9Schristos 
115*7bdf38e5Schristos 		expect_zu_le(floor, extent_size,
116a0698ed9Schristos 		    "Floor should be <= (floor=%zu, extent_size=%zu, ceil=%zu)",
117a0698ed9Schristos 		    floor, extent_size, ceil);
118*7bdf38e5Schristos 		expect_zu_ge(ceil, extent_size,
119a0698ed9Schristos 		    "Ceiling should be >= (floor=%zu, extent_size=%zu, "
120a0698ed9Schristos 		    "ceil=%zu)", floor, extent_size, ceil);
121a0698ed9Schristos 
122*7bdf38e5Schristos 		expect_zu_le(floor_prev, floor, "Floor should be monotonic "
123a0698ed9Schristos 		    "(floor_prev=%zu, floor=%zu, extent_size=%zu, ceil=%zu)",
124a0698ed9Schristos 		    floor_prev, floor, extent_size, ceil);
125*7bdf38e5Schristos 		expect_zu_le(ceil_prev, ceil, "Ceiling should be monotonic "
126a0698ed9Schristos 		    "(floor=%zu, extent_size=%zu, ceil_prev=%zu, ceil=%zu)",
127a0698ed9Schristos 		    floor, extent_size, ceil_prev, ceil);
128a0698ed9Schristos 
129a0698ed9Schristos 		floor_prev = floor;
130a0698ed9Schristos 		ceil_prev = ceil;
131a0698ed9Schristos 	}
132a0698ed9Schristos }
133a0698ed9Schristos TEST_END
134a0698ed9Schristos 
135a0698ed9Schristos int
136a0698ed9Schristos main(void) {
137a0698ed9Schristos 	return test(
138a0698ed9Schristos 	    test_small_extent_size,
139a0698ed9Schristos 	    test_large_extent_size,
140a0698ed9Schristos 	    test_monotonic);
141a0698ed9Schristos }
142