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