2e6f51648fd8962dd67e2c73872fb088ebcad542
[folly.git] / folly / synchronization / 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/synchronization/Baton.h>
18
19 #include <thread>
20
21 #include <folly/portability/GTest.h>
22 #include <folly/synchronization/test/BatonTestHelpers.h>
23 #include <folly/test/DeterministicSchedule.h>
24
25 using namespace folly;
26 using namespace folly::test;
27 using folly::detail::EmulatedFutexAtomic;
28
29 /// Basic test
30
31 TEST(Baton, basic_single_poster_blocking) {
32   run_basic_test<std::atomic, true, true>();
33   run_basic_test<EmulatedFutexAtomic, true, true>();
34   run_basic_test<DeterministicAtomic, true, true>();
35 }
36
37 TEST(Baton, basic_single_poster_nonblocking) {
38   run_basic_test<std::atomic, true, false>();
39   run_basic_test<EmulatedFutexAtomic, true, false>();
40   run_basic_test<DeterministicAtomic, true, false>();
41 }
42
43 TEST(Baton, basic_multi_poster_blocking) {
44   run_basic_test<std::atomic, false, true>();
45 }
46
47 TEST(Baton, basic_multi_poster_nonblocking) {
48   run_basic_test<std::atomic, false, false>();
49 }
50
51 /// Ping pong tests
52
53 TEST(Baton, pingpong_single_poster_blocking) {
54   DSched sched(DSched::uniform(0));
55
56   run_pingpong_test<DeterministicAtomic, true, true>(1000);
57 }
58
59 TEST(Baton, pingpong_single_poster_nonblocking) {
60   DSched sched(DSched::uniform(0));
61
62   run_pingpong_test<DeterministicAtomic, true, false>(1000);
63 }
64
65 TEST(Baton, pingpong_multi_poster_blocking) {
66   DSched sched(DSched::uniform(0));
67
68   run_pingpong_test<DeterministicAtomic, false, true>(1000);
69 }
70
71 TEST(Baton, pingpong_multi_poster_nonblocking) {
72   DSched sched(DSched::uniform(0));
73
74   run_pingpong_test<DeterministicAtomic, false, false>(1000);
75 }
76
77 /// Timed wait tests - Nonblocking Baton does not support timed_wait()
78
79 // Timed wait basic system clock tests
80
81 TEST(Baton, timed_wait_basic_system_clock_single_poster) {
82   run_basic_timed_wait_tests<std::atomic, std::chrono::system_clock, true>();
83   run_basic_timed_wait_tests<
84       EmulatedFutexAtomic,
85       std::chrono::system_clock,
86       true>();
87   run_basic_timed_wait_tests<
88       DeterministicAtomic,
89       std::chrono::system_clock,
90       true>();
91 }
92
93 TEST(Baton, timed_wait_basic_system_clock_multi_poster) {
94   run_basic_timed_wait_tests<std::atomic, std::chrono::system_clock, false>();
95   run_basic_timed_wait_tests<
96       EmulatedFutexAtomic,
97       std::chrono::system_clock,
98       false>();
99   run_basic_timed_wait_tests<
100       DeterministicAtomic,
101       std::chrono::system_clock,
102       false>();
103 }
104
105 // Timed wait timeout system clock tests
106
107 TEST(Baton, timed_wait_timeout_system_clock_single_poster) {
108   run_timed_wait_tmo_tests<std::atomic, std::chrono::system_clock, true>();
109   run_timed_wait_tmo_tests<
110       EmulatedFutexAtomic,
111       std::chrono::system_clock,
112       true>();
113   run_timed_wait_tmo_tests<
114       DeterministicAtomic,
115       std::chrono::system_clock,
116       true>();
117 }
118
119 TEST(Baton, timed_wait_timeout_system_clock_multi_poster) {
120   run_timed_wait_tmo_tests<std::atomic, std::chrono::system_clock, false>();
121   run_timed_wait_tmo_tests<
122       EmulatedFutexAtomic,
123       std::chrono::system_clock,
124       false>();
125   run_timed_wait_tmo_tests<
126       DeterministicAtomic,
127       std::chrono::system_clock,
128       false>();
129 }
130
131 // Timed wait regular system clock tests
132
133 TEST(Baton, timed_wait_system_clock_single_poster) {
134   run_timed_wait_regular_test<std::atomic, std::chrono::system_clock, true>();
135   run_timed_wait_regular_test<
136       EmulatedFutexAtomic,
137       std::chrono::system_clock,
138       true>();
139   run_timed_wait_regular_test<
140       DeterministicAtomic,
141       std::chrono::system_clock,
142       true>();
143 }
144
145 TEST(Baton, timed_wait_system_clock_multi_poster) {
146   run_timed_wait_regular_test<std::atomic, std::chrono::system_clock, false>();
147   run_timed_wait_regular_test<
148       EmulatedFutexAtomic,
149       std::chrono::system_clock,
150       false>();
151   run_timed_wait_regular_test<
152       DeterministicAtomic,
153       std::chrono::system_clock,
154       false>();
155 }
156
157 // Timed wait basic steady clock tests
158
159 TEST(Baton, timed_wait_basic_steady_clock_single_poster) {
160   run_basic_timed_wait_tests<std::atomic, std::chrono::steady_clock, true>();
161   run_basic_timed_wait_tests<
162       EmulatedFutexAtomic,
163       std::chrono::steady_clock,
164       true>();
165   run_basic_timed_wait_tests<
166       DeterministicAtomic,
167       std::chrono::steady_clock,
168       true>();
169 }
170
171 TEST(Baton, timed_wait_basic_steady_clock_multi_poster) {
172   run_basic_timed_wait_tests<std::atomic, std::chrono::steady_clock, false>();
173   run_basic_timed_wait_tests<
174       EmulatedFutexAtomic,
175       std::chrono::steady_clock,
176       false>();
177   run_basic_timed_wait_tests<
178       DeterministicAtomic,
179       std::chrono::steady_clock,
180       false>();
181 }
182
183 // Timed wait timeout steady clock tests
184
185 TEST(Baton, timed_wait_timeout_steady_clock_single_poster) {
186   run_timed_wait_tmo_tests<std::atomic, std::chrono::steady_clock, true>();
187   run_timed_wait_tmo_tests<
188       EmulatedFutexAtomic,
189       std::chrono::steady_clock,
190       true>();
191   run_timed_wait_tmo_tests<
192       DeterministicAtomic,
193       std::chrono::steady_clock,
194       true>();
195 }
196
197 TEST(Baton, timed_wait_timeout_steady_clock_multi_poster) {
198   run_timed_wait_tmo_tests<std::atomic, std::chrono::steady_clock, false>();
199   run_timed_wait_tmo_tests<
200       EmulatedFutexAtomic,
201       std::chrono::steady_clock,
202       false>();
203   run_timed_wait_tmo_tests<
204       DeterministicAtomic,
205       std::chrono::steady_clock,
206       false>();
207 }
208
209 // Timed wait regular steady clock tests
210
211 TEST(Baton, timed_wait_steady_clock_single_poster) {
212   run_timed_wait_regular_test<std::atomic, std::chrono::steady_clock, true>();
213   run_timed_wait_regular_test<
214       EmulatedFutexAtomic,
215       std::chrono::steady_clock,
216       true>();
217   run_timed_wait_regular_test<
218       DeterministicAtomic,
219       std::chrono::steady_clock,
220       true>();
221 }
222
223 TEST(Baton, timed_wait_steady_clock_multi_poster) {
224   run_timed_wait_regular_test<std::atomic, std::chrono::steady_clock, false>();
225   run_timed_wait_regular_test<
226       EmulatedFutexAtomic,
227       std::chrono::steady_clock,
228       false>();
229   run_timed_wait_regular_test<
230       DeterministicAtomic,
231       std::chrono::steady_clock,
232       false>();
233 }
234
235 /// Try wait tests
236
237 TEST(Baton, try_wait_single_poster_blocking) {
238   run_try_wait_tests<std::atomic, true, true>();
239   run_try_wait_tests<EmulatedFutexAtomic, true, true>();
240   run_try_wait_tests<DeterministicAtomic, true, true>();
241 }
242
243 TEST(Baton, try_wait_single_poster_nonblocking) {
244   run_try_wait_tests<std::atomic, true, false>();
245   run_try_wait_tests<EmulatedFutexAtomic, true, false>();
246   run_try_wait_tests<DeterministicAtomic, true, false>();
247 }
248
249 TEST(Baton, try_wait_multi_poster_blocking) {
250   run_try_wait_tests<std::atomic, false, true>();
251   run_try_wait_tests<EmulatedFutexAtomic, false, true>();
252   run_try_wait_tests<DeterministicAtomic, false, true>();
253 }
254
255 TEST(Baton, try_wait_multi_poster_nonblocking) {
256   run_try_wait_tests<std::atomic, false, false>();
257   run_try_wait_tests<EmulatedFutexAtomic, false, false>();
258   run_try_wait_tests<DeterministicAtomic, false, false>();
259 }
260
261 /// Multi-producer tests
262
263 TEST(Baton, multi_producer_single_poster_blocking) {
264   run_try_wait_tests<std::atomic, true, true>();
265   run_try_wait_tests<EmulatedFutexAtomic, true, true>();
266   run_try_wait_tests<DeterministicAtomic, true, true>();
267 }
268
269 TEST(Baton, multi_producer_single_poster_nonblocking) {
270   run_try_wait_tests<std::atomic, true, false>();
271   run_try_wait_tests<EmulatedFutexAtomic, true, false>();
272   run_try_wait_tests<DeterministicAtomic, true, false>();
273 }
274
275 TEST(Baton, multi_producer_multi_poster_blocking) {
276   run_try_wait_tests<std::atomic, false, true>();
277   run_try_wait_tests<EmulatedFutexAtomic, false, true>();
278   run_try_wait_tests<DeterministicAtomic, false, true>();
279 }
280
281 TEST(Baton, multi_producer_multi_poster_nonblocking) {
282   run_try_wait_tests<std::atomic, false, false>();
283   run_try_wait_tests<EmulatedFutexAtomic, false, false>();
284   run_try_wait_tests<DeterministicAtomic, false, false>();
285 }