Add Baton variants with multiple posters and with a non-blocking waiter
[folly.git] / folly / test / BatonTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/Baton.h>
18 #include <folly/test/BatonTestHelpers.h>
19 #include <folly/test/DeterministicSchedule.h>
20 #include <folly/portability/GTest.h>
21
22 #include <thread>
23
24 using namespace folly;
25 using namespace folly::test;
26 using folly::detail::EmulatedFutexAtomic;
27
28 /// Basic test
29
30 TEST(Baton, basic_single_poster_blocking) {
31   run_basic_test<std::atomic, true, true>();
32   run_basic_test<EmulatedFutexAtomic, true, true>();
33   run_basic_test<DeterministicAtomic, true, true>();
34 }
35
36 TEST(Baton, basic_single_poster_nonblocking) {
37   run_basic_test<std::atomic, true, false>();
38   run_basic_test<EmulatedFutexAtomic, true, false>();
39   run_basic_test<DeterministicAtomic, true, false>();
40 }
41
42 TEST(Baton, basic_multi_poster_blocking) {
43   run_basic_test<std::atomic, false, true>();
44 }
45
46 TEST(Baton, basic_multi_poster_nonblocking) {
47   run_basic_test<std::atomic, false, false>();
48 }
49
50 /// Ping pong tests
51
52 TEST(Baton, pingpong_single_poster_blocking) {
53   DSched sched(DSched::uniform(0));
54
55   run_pingpong_test<DeterministicAtomic, true, true>(1000);
56 }
57
58 TEST(Baton, pingpong_single_poster_nonblocking) {
59   DSched sched(DSched::uniform(0));
60
61   run_pingpong_test<DeterministicAtomic, true, false>(1000);
62 }
63
64 TEST(Baton, pingpong_multi_poster_blocking) {
65   DSched sched(DSched::uniform(0));
66
67   run_pingpong_test<DeterministicAtomic, false, true>(1000);
68 }
69
70 TEST(Baton, pingpong_multi_poster_nonblocking) {
71   DSched sched(DSched::uniform(0));
72
73   run_pingpong_test<DeterministicAtomic, false, false>(1000);
74 }
75
76 /// Timed wait tests - Nonblocking Baton does not support timed_wait()
77
78 // Timed wait basic system clock tests
79
80 TEST(Baton, timed_wait_basic_system_clock_single_poster) {
81   run_basic_timed_wait_tests<std::atomic, std::chrono::system_clock, true>();
82   run_basic_timed_wait_tests<
83       EmulatedFutexAtomic,
84       std::chrono::system_clock,
85       true>();
86   run_basic_timed_wait_tests<
87       DeterministicAtomic,
88       std::chrono::system_clock,
89       true>();
90 }
91
92 TEST(Baton, timed_wait_basic_system_clock_multi_poster) {
93   run_basic_timed_wait_tests<std::atomic, std::chrono::system_clock, false>();
94   run_basic_timed_wait_tests<
95       EmulatedFutexAtomic,
96       std::chrono::system_clock,
97       false>();
98   run_basic_timed_wait_tests<
99       DeterministicAtomic,
100       std::chrono::system_clock,
101       false>();
102 }
103
104 // Timed wait timeout system clock tests
105
106 TEST(Baton, timed_wait_timeout_system_clock_single_poster) {
107   run_timed_wait_tmo_tests<std::atomic, std::chrono::system_clock, true>();
108   run_timed_wait_tmo_tests<
109       EmulatedFutexAtomic,
110       std::chrono::system_clock,
111       true>();
112   run_timed_wait_tmo_tests<
113       DeterministicAtomic,
114       std::chrono::system_clock,
115       true>();
116 }
117
118 TEST(Baton, timed_wait_timeout_system_clock_multi_poster) {
119   run_timed_wait_tmo_tests<std::atomic, std::chrono::system_clock, false>();
120   run_timed_wait_tmo_tests<
121       EmulatedFutexAtomic,
122       std::chrono::system_clock,
123       false>();
124   run_timed_wait_tmo_tests<
125       DeterministicAtomic,
126       std::chrono::system_clock,
127       false>();
128 }
129
130 // Timed wait regular system clock tests
131
132 TEST(Baton, timed_wait_system_clock_single_poster) {
133   run_timed_wait_regular_test<std::atomic, std::chrono::system_clock, true>();
134   run_timed_wait_regular_test<
135       EmulatedFutexAtomic,
136       std::chrono::system_clock,
137       true>();
138   run_timed_wait_regular_test<
139       DeterministicAtomic,
140       std::chrono::system_clock,
141       true>();
142 }
143
144 TEST(Baton, timed_wait_system_clock_multi_poster) {
145   run_timed_wait_regular_test<std::atomic, std::chrono::system_clock, false>();
146   run_timed_wait_regular_test<
147       EmulatedFutexAtomic,
148       std::chrono::system_clock,
149       false>();
150   run_timed_wait_regular_test<
151       DeterministicAtomic,
152       std::chrono::system_clock,
153       false>();
154 }
155
156 // Timed wait basic steady clock tests
157
158 TEST(Baton, timed_wait_basic_steady_clock_single_poster) {
159   run_basic_timed_wait_tests<std::atomic, std::chrono::steady_clock, true>();
160   run_basic_timed_wait_tests<
161       EmulatedFutexAtomic,
162       std::chrono::steady_clock,
163       true>();
164   run_basic_timed_wait_tests<
165       DeterministicAtomic,
166       std::chrono::steady_clock,
167       true>();
168 }
169
170 TEST(Baton, timed_wait_basic_steady_clock_multi_poster) {
171   run_basic_timed_wait_tests<std::atomic, std::chrono::steady_clock, false>();
172   run_basic_timed_wait_tests<
173       EmulatedFutexAtomic,
174       std::chrono::steady_clock,
175       false>();
176   run_basic_timed_wait_tests<
177       DeterministicAtomic,
178       std::chrono::steady_clock,
179       false>();
180 }
181
182 // Timed wait timeout steady clock tests
183
184 TEST(Baton, timed_wait_timeout_steady_clock_single_poster) {
185   run_timed_wait_tmo_tests<std::atomic, std::chrono::steady_clock, true>();
186   run_timed_wait_tmo_tests<
187       EmulatedFutexAtomic,
188       std::chrono::steady_clock,
189       true>();
190   run_timed_wait_tmo_tests<
191       DeterministicAtomic,
192       std::chrono::steady_clock,
193       true>();
194 }
195
196 TEST(Baton, timed_wait_timeout_steady_clock_multi_poster) {
197   run_timed_wait_tmo_tests<std::atomic, std::chrono::steady_clock, false>();
198   run_timed_wait_tmo_tests<
199       EmulatedFutexAtomic,
200       std::chrono::steady_clock,
201       false>();
202   run_timed_wait_tmo_tests<
203       DeterministicAtomic,
204       std::chrono::steady_clock,
205       false>();
206 }
207
208 // Timed wait regular steady clock tests
209
210 TEST(Baton, timed_wait_steady_clock_single_poster) {
211   run_timed_wait_regular_test<std::atomic, std::chrono::steady_clock, true>();
212   run_timed_wait_regular_test<
213       EmulatedFutexAtomic,
214       std::chrono::steady_clock,
215       true>();
216   run_timed_wait_regular_test<
217       DeterministicAtomic,
218       std::chrono::steady_clock,
219       true>();
220 }
221
222 TEST(Baton, timed_wait_steady_clock_multi_poster) {
223   run_timed_wait_regular_test<std::atomic, std::chrono::steady_clock, false>();
224   run_timed_wait_regular_test<
225       EmulatedFutexAtomic,
226       std::chrono::steady_clock,
227       false>();
228   run_timed_wait_regular_test<
229       DeterministicAtomic,
230       std::chrono::steady_clock,
231       false>();
232 }
233
234 /// Try wait tests
235
236 TEST(Baton, try_wait_single_poster_blocking) {
237   run_try_wait_tests<std::atomic, true, true>();
238   run_try_wait_tests<EmulatedFutexAtomic, true, true>();
239   run_try_wait_tests<DeterministicAtomic, true, true>();
240 }
241
242 TEST(Baton, try_wait_single_poster_nonblocking) {
243   run_try_wait_tests<std::atomic, true, false>();
244   run_try_wait_tests<EmulatedFutexAtomic, true, false>();
245   run_try_wait_tests<DeterministicAtomic, true, false>();
246 }
247
248 TEST(Baton, try_wait_multi_poster_blocking) {
249   run_try_wait_tests<std::atomic, false, true>();
250   run_try_wait_tests<EmulatedFutexAtomic, false, true>();
251   run_try_wait_tests<DeterministicAtomic, false, true>();
252 }
253
254 TEST(Baton, try_wait_multi_poster_nonblocking) {
255   run_try_wait_tests<std::atomic, false, false>();
256   run_try_wait_tests<EmulatedFutexAtomic, false, false>();
257   run_try_wait_tests<DeterministicAtomic, false, false>();
258 }
259
260 /// Multi-producer tests
261
262 TEST(Baton, multi_producer_single_poster_blocking) {
263   run_try_wait_tests<std::atomic, true, true>();
264   run_try_wait_tests<EmulatedFutexAtomic, true, true>();
265   run_try_wait_tests<DeterministicAtomic, true, true>();
266 }
267
268 TEST(Baton, multi_producer_single_poster_nonblocking) {
269   run_try_wait_tests<std::atomic, true, false>();
270   run_try_wait_tests<EmulatedFutexAtomic, true, false>();
271   run_try_wait_tests<DeterministicAtomic, true, false>();
272 }
273
274 TEST(Baton, multi_producer_multi_poster_blocking) {
275   run_try_wait_tests<std::atomic, false, true>();
276   run_try_wait_tests<EmulatedFutexAtomic, false, true>();
277   run_try_wait_tests<DeterministicAtomic, false, true>();
278 }
279
280 TEST(Baton, multi_producer_multi_poster_nonblocking) {
281   run_try_wait_tests<std::atomic, false, false>();
282   run_try_wait_tests<EmulatedFutexAtomic, false, false>();
283   run_try_wait_tests<DeterministicAtomic, false, false>();
284 }