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