xref: /aosp_15_r20/external/jemalloc_new/test/unit/prng.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1 #include "test/jemalloc_test.h"
2 
3 static void
test_prng_lg_range_u32(bool atomic)4 test_prng_lg_range_u32(bool atomic) {
5 	atomic_u32_t sa, sb;
6 	uint32_t ra, rb;
7 	unsigned lg_range;
8 
9 	atomic_store_u32(&sa, 42, ATOMIC_RELAXED);
10 	ra = prng_lg_range_u32(&sa, 32, atomic);
11 	atomic_store_u32(&sa, 42, ATOMIC_RELAXED);
12 	rb = prng_lg_range_u32(&sa, 32, atomic);
13 	assert_u32_eq(ra, rb,
14 	    "Repeated generation should produce repeated results");
15 
16 	atomic_store_u32(&sb, 42, ATOMIC_RELAXED);
17 	rb = prng_lg_range_u32(&sb, 32, atomic);
18 	assert_u32_eq(ra, rb,
19 	    "Equivalent generation should produce equivalent results");
20 
21 	atomic_store_u32(&sa, 42, ATOMIC_RELAXED);
22 	ra = prng_lg_range_u32(&sa, 32, atomic);
23 	rb = prng_lg_range_u32(&sa, 32, atomic);
24 	assert_u32_ne(ra, rb,
25 	    "Full-width results must not immediately repeat");
26 
27 	atomic_store_u32(&sa, 42, ATOMIC_RELAXED);
28 	ra = prng_lg_range_u32(&sa, 32, atomic);
29 	for (lg_range = 31; lg_range > 0; lg_range--) {
30 		atomic_store_u32(&sb, 42, ATOMIC_RELAXED);
31 		rb = prng_lg_range_u32(&sb, lg_range, atomic);
32 		assert_u32_eq((rb & (UINT32_C(0xffffffff) << lg_range)),
33 		    0, "High order bits should be 0, lg_range=%u", lg_range);
34 		assert_u32_eq(rb, (ra >> (32 - lg_range)),
35 		    "Expected high order bits of full-width result, "
36 		    "lg_range=%u", lg_range);
37 	}
38 }
39 
40 static void
test_prng_lg_range_u64(void)41 test_prng_lg_range_u64(void) {
42 	uint64_t sa, sb, ra, rb;
43 	unsigned lg_range;
44 
45 	sa = 42;
46 	ra = prng_lg_range_u64(&sa, 64);
47 	sa = 42;
48 	rb = prng_lg_range_u64(&sa, 64);
49 	assert_u64_eq(ra, rb,
50 	    "Repeated generation should produce repeated results");
51 
52 	sb = 42;
53 	rb = prng_lg_range_u64(&sb, 64);
54 	assert_u64_eq(ra, rb,
55 	    "Equivalent generation should produce equivalent results");
56 
57 	sa = 42;
58 	ra = prng_lg_range_u64(&sa, 64);
59 	rb = prng_lg_range_u64(&sa, 64);
60 	assert_u64_ne(ra, rb,
61 	    "Full-width results must not immediately repeat");
62 
63 	sa = 42;
64 	ra = prng_lg_range_u64(&sa, 64);
65 	for (lg_range = 63; lg_range > 0; lg_range--) {
66 		sb = 42;
67 		rb = prng_lg_range_u64(&sb, lg_range);
68 		assert_u64_eq((rb & (UINT64_C(0xffffffffffffffff) << lg_range)),
69 		    0, "High order bits should be 0, lg_range=%u", lg_range);
70 		assert_u64_eq(rb, (ra >> (64 - lg_range)),
71 		    "Expected high order bits of full-width result, "
72 		    "lg_range=%u", lg_range);
73 	}
74 }
75 
76 static void
test_prng_lg_range_zu(bool atomic)77 test_prng_lg_range_zu(bool atomic) {
78 	atomic_zu_t sa, sb;
79 	size_t ra, rb;
80 	unsigned lg_range;
81 
82 	atomic_store_zu(&sa, 42, ATOMIC_RELAXED);
83 	ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
84 	atomic_store_zu(&sa, 42, ATOMIC_RELAXED);
85 	rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
86 	assert_zu_eq(ra, rb,
87 	    "Repeated generation should produce repeated results");
88 
89 	atomic_store_zu(&sb, 42, ATOMIC_RELAXED);
90 	rb = prng_lg_range_zu(&sb, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
91 	assert_zu_eq(ra, rb,
92 	    "Equivalent generation should produce equivalent results");
93 
94 	atomic_store_zu(&sa, 42, ATOMIC_RELAXED);
95 	ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
96 	rb = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
97 	assert_zu_ne(ra, rb,
98 	    "Full-width results must not immediately repeat");
99 
100 	atomic_store_zu(&sa, 42, ATOMIC_RELAXED);
101 	ra = prng_lg_range_zu(&sa, ZU(1) << (3 + LG_SIZEOF_PTR), atomic);
102 	for (lg_range = (ZU(1) << (3 + LG_SIZEOF_PTR)) - 1; lg_range > 0;
103 	    lg_range--) {
104 		atomic_store_zu(&sb, 42, ATOMIC_RELAXED);
105 		rb = prng_lg_range_zu(&sb, lg_range, atomic);
106 		assert_zu_eq((rb & (SIZE_T_MAX << lg_range)),
107 		    0, "High order bits should be 0, lg_range=%u", lg_range);
108 		assert_zu_eq(rb, (ra >> ((ZU(1) << (3 + LG_SIZEOF_PTR)) -
109 		    lg_range)), "Expected high order bits of full-width "
110 		    "result, lg_range=%u", lg_range);
111 	}
112 }
113 
TEST_BEGIN(test_prng_lg_range_u32_nonatomic)114 TEST_BEGIN(test_prng_lg_range_u32_nonatomic) {
115 	test_prng_lg_range_u32(false);
116 }
117 TEST_END
118 
TEST_BEGIN(test_prng_lg_range_u32_atomic)119 TEST_BEGIN(test_prng_lg_range_u32_atomic) {
120 	test_prng_lg_range_u32(true);
121 }
122 TEST_END
123 
TEST_BEGIN(test_prng_lg_range_u64_nonatomic)124 TEST_BEGIN(test_prng_lg_range_u64_nonatomic) {
125 	test_prng_lg_range_u64();
126 }
127 TEST_END
128 
TEST_BEGIN(test_prng_lg_range_zu_nonatomic)129 TEST_BEGIN(test_prng_lg_range_zu_nonatomic) {
130 	test_prng_lg_range_zu(false);
131 }
132 TEST_END
133 
TEST_BEGIN(test_prng_lg_range_zu_atomic)134 TEST_BEGIN(test_prng_lg_range_zu_atomic) {
135 	test_prng_lg_range_zu(true);
136 }
137 TEST_END
138 
139 static void
test_prng_range_u32(bool atomic)140 test_prng_range_u32(bool atomic) {
141 	uint32_t range;
142 #define MAX_RANGE	10000000
143 #define RANGE_STEP	97
144 #define NREPS		10
145 
146 	for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
147 		atomic_u32_t s;
148 		unsigned rep;
149 
150 		atomic_store_u32(&s, range, ATOMIC_RELAXED);
151 		for (rep = 0; rep < NREPS; rep++) {
152 			uint32_t r = prng_range_u32(&s, range, atomic);
153 
154 			assert_u32_lt(r, range, "Out of range");
155 		}
156 	}
157 }
158 
159 static void
test_prng_range_u64(void)160 test_prng_range_u64(void) {
161 	uint64_t range;
162 #define MAX_RANGE	10000000
163 #define RANGE_STEP	97
164 #define NREPS		10
165 
166 	for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
167 		uint64_t s;
168 		unsigned rep;
169 
170 		s = range;
171 		for (rep = 0; rep < NREPS; rep++) {
172 			uint64_t r = prng_range_u64(&s, range);
173 
174 			assert_u64_lt(r, range, "Out of range");
175 		}
176 	}
177 }
178 
179 static void
test_prng_range_zu(bool atomic)180 test_prng_range_zu(bool atomic) {
181 	size_t range;
182 #define MAX_RANGE	10000000
183 #define RANGE_STEP	97
184 #define NREPS		10
185 
186 	for (range = 2; range < MAX_RANGE; range += RANGE_STEP) {
187 		atomic_zu_t s;
188 		unsigned rep;
189 
190 		atomic_store_zu(&s, range, ATOMIC_RELAXED);
191 		for (rep = 0; rep < NREPS; rep++) {
192 			size_t r = prng_range_zu(&s, range, atomic);
193 
194 			assert_zu_lt(r, range, "Out of range");
195 		}
196 	}
197 }
198 
TEST_BEGIN(test_prng_range_u32_nonatomic)199 TEST_BEGIN(test_prng_range_u32_nonatomic) {
200 	test_prng_range_u32(false);
201 }
202 TEST_END
203 
TEST_BEGIN(test_prng_range_u32_atomic)204 TEST_BEGIN(test_prng_range_u32_atomic) {
205 	test_prng_range_u32(true);
206 }
207 TEST_END
208 
TEST_BEGIN(test_prng_range_u64_nonatomic)209 TEST_BEGIN(test_prng_range_u64_nonatomic) {
210 	test_prng_range_u64();
211 }
212 TEST_END
213 
TEST_BEGIN(test_prng_range_zu_nonatomic)214 TEST_BEGIN(test_prng_range_zu_nonatomic) {
215 	test_prng_range_zu(false);
216 }
217 TEST_END
218 
TEST_BEGIN(test_prng_range_zu_atomic)219 TEST_BEGIN(test_prng_range_zu_atomic) {
220 	test_prng_range_zu(true);
221 }
222 TEST_END
223 
224 int
main(void)225 main(void) {
226 	return test(
227 	    test_prng_lg_range_u32_nonatomic,
228 	    test_prng_lg_range_u32_atomic,
229 	    test_prng_lg_range_u64_nonatomic,
230 	    test_prng_lg_range_zu_nonatomic,
231 	    test_prng_lg_range_zu_atomic,
232 	    test_prng_range_u32_nonatomic,
233 	    test_prng_range_u32_atomic,
234 	    test_prng_range_u64_nonatomic,
235 	    test_prng_range_zu_nonatomic,
236 	    test_prng_range_zu_atomic);
237 }
238