]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/thread/test/test_time_jumps.cpp
706bafa479233a1f03825d24fb6d01c04924ad1c
[ceph.git] / ceph / src / boost / libs / thread / test / test_time_jumps.cpp
1 #ifdef _WIN32
2 #include <windows.h>
3 #else
4 #include <sys/time.h>
5 #endif
6
7 #include "boost/bind/bind.hpp"
8 #include "boost/chrono.hpp"
9 #include "boost/chrono/ceil.hpp"
10 #include "boost/date_time.hpp"
11 #include "boost/thread/concurrent_queues/sync_priority_queue.hpp"
12 #include "boost/thread/concurrent_queues/sync_timed_queue.hpp"
13 #include "boost/thread/future.hpp"
14 #include "boost/thread/mutex.hpp"
15 #include "boost/thread/recursive_mutex.hpp"
16 #include "boost/thread/shared_lock_guard.hpp"
17 #include "boost/thread/shared_mutex.hpp"
18 #include "boost/thread/thread.hpp"
19
20 #include <iomanip>
21 #ifdef TEST_CPP14_FEATURES
22 #include <future>
23 #include <mutex>
24 #include <shared_mutex>
25 #include <thread>
26 #endif
27
28 /******************************************************************************/
29
30 /*
31 * Summary:
32 *
33 * This code tests the behavior of time-related functions in the presence of
34 * system clock changes (jumps). It requires root/Administrator privileges in
35 * order to run because it changes the system clock. NTP should also be disabled
36 * while running this code so that NTP can't change the system clock.
37 *
38 * Each function to be tested is executed five times. The amount of time the
39 * function waits before returning is measured against the amount of time the
40 * function was expected to wait. If the difference exceeds a threshold value
41 * (defined below) then the test fails.
42 *
43 * The following values are intentially:
44 * - more than 200 milliseconds
45 * - more than 200 milliseconds apart
46 * - not a multiple of 100 milliseconds
47 * - not a multiple of each other
48 * - don't sum or diff to a multiple of 100 milliseconds
49 */
50 const long long s_waitMs = 580;
51 const long long s_shortJumpMs = 230;
52 const long long s_longJumpMs = 870; // Causes additional, unavoidable failures when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is disabled
53 const long long s_sleepBeforeJumpMs = 110;
54
55 #ifdef _WIN32
56 const long long s_maxEarlyErrorMs = 10
57 + 100; // Windows is unpredictable, especially in a VM, so allow extra time if the function returns early
58 const long long s_maxLateErrorMs = 110 // due to polling, functions may not return for up to 100 milliseconds after they are supposed to
59 + 100; // Windows is slow, especially in a VM, so allow extra time for the functions to return
60 #else
61 const long long s_maxEarlyErrorMs = 10;
62 const long long s_maxLateErrorMs = 110; // Due to polling, functions may not return for up to 100 milliseconds after they are supposed to
63 #endif
64
65 int g_numTestsRun = 0;
66 int g_numTestsPassed = 0;
67 int g_numTestsFailed = 0;
68
69 /******************************************************************************/
70
71 // A custom clock based off the system clock but with a different epoch.
72
73 namespace custom
74 {
75 class custom_boost_clock
76 {
77 public:
78 typedef boost::chrono::microseconds duration; // intentionally not nanoseconds
79 typedef duration::rep rep;
80 typedef duration::period period;
81 typedef boost::chrono::time_point<custom_boost_clock> time_point;
82 static bool is_steady;
83
84 static time_point now();
85 };
86
87 bool custom_boost_clock::is_steady = false;
88
89 custom_boost_clock::time_point custom_boost_clock::now()
90 {
91 return time_point(boost::chrono::ceil<duration>(boost::chrono::system_clock::now().time_since_epoch()) - boost::chrono::hours(10 * 365 * 24));
92 }
93
94 #ifdef TEST_CPP14_FEATURES
95 class custom_std_clock
96 {
97 public:
98 typedef std::chrono::microseconds duration; // intentionally not nanoseconds
99 typedef duration::rep rep;
100 typedef duration::period period;
101 typedef std::chrono::time_point<custom_std_clock> time_point;
102 static bool is_steady;
103
104 static time_point now();
105 };
106
107 bool custom_std_clock::is_steady = false;
108
109 custom_std_clock::time_point custom_std_clock::now()
110 {
111 return time_point(std::chrono::duration_cast<duration>(std::chrono::system_clock::now().time_since_epoch()) - std::chrono::hours(10 * 365 * 24));
112 }
113 #endif
114 }
115
116 /******************************************************************************/
117
118 template <typename MutexType = boost::mutex, typename CondType = boost::condition_variable>
119 struct BoostHelper
120 {
121 typedef MutexType mutex;
122 typedef CondType cond;
123
124 typedef boost::lock_guard<MutexType> lock_guard;
125 typedef boost::unique_lock<MutexType> unique_lock;
126
127 typedef boost::chrono::milliseconds milliseconds;
128 typedef boost::chrono::nanoseconds nanoseconds;
129
130 typedef boost::chrono::system_clock system_clock;
131 typedef boost::chrono::steady_clock steady_clock;
132 typedef custom::custom_boost_clock custom_clock;
133
134 typedef system_clock::time_point system_time_point;
135 typedef steady_clock::time_point steady_time_point;
136 typedef custom_clock::time_point custom_time_point;
137
138 typedef boost::cv_status cv_status;
139 typedef boost::future_status future_status;
140
141 typedef boost::packaged_task<bool> packaged_task;
142 typedef boost::future<bool> future;
143 typedef boost::shared_future<bool> shared_future;
144
145 typedef boost::thread thread;
146
147 static const milliseconds waitDur;
148
149 template <typename T>
150 static void sleep_for(T d)
151 {
152 boost::this_thread::sleep_for(d);
153 }
154
155 template <typename T>
156 static void sleep_for_no_int(T d)
157 {
158 boost::this_thread::no_interruption_point::sleep_for(d);
159 }
160
161 template <typename T>
162 static void sleep_until(T t)
163 {
164 boost::this_thread::sleep_until(t);
165 }
166
167 template <typename T>
168 static void sleep_until_no_int(T t)
169 {
170 boost::this_thread::no_interruption_point::sleep_until(t);
171 }
172
173 static system_time_point systemNow()
174 {
175 return system_clock::now();
176 }
177
178 static steady_time_point steadyNow()
179 {
180 return steady_clock::now();
181 }
182
183 static custom_time_point customNow()
184 {
185 return custom_clock::now();
186 }
187
188 template <class ToDuration, class Rep, class Period>
189 static ToDuration duration_cast(const boost::chrono::duration<Rep, Period>& d)
190 {
191 return boost::chrono::duration_cast<ToDuration>(d);
192 }
193
194 static milliseconds zero()
195 {
196 return milliseconds(0);
197 }
198 };
199
200 template <typename MutexType, typename CondType>
201 const typename BoostHelper<MutexType, CondType>::milliseconds
202 BoostHelper<MutexType, CondType>::waitDur = typename BoostHelper<MutexType, CondType>::milliseconds(s_waitMs);
203
204 #ifdef TEST_CPP14_FEATURES
205 template <typename MutexType = std::mutex, typename CondType = std::condition_variable>
206 struct StdHelper
207 {
208 typedef MutexType mutex;
209 typedef CondType cond;
210
211 typedef std::lock_guard<MutexType> lock_guard;
212 typedef std::unique_lock<MutexType> unique_lock;
213
214 typedef std::chrono::milliseconds milliseconds;
215 typedef std::chrono::nanoseconds nanoseconds;
216
217 typedef std::chrono::system_clock system_clock;
218 typedef std::chrono::steady_clock steady_clock;
219 typedef custom::custom_std_clock custom_clock;
220
221 typedef system_clock::time_point system_time_point;
222 typedef steady_clock::time_point steady_time_point;
223 typedef custom_clock::time_point custom_time_point;
224
225 typedef std::cv_status cv_status;
226 typedef std::future_status future_status;
227
228 typedef std::packaged_task<bool()> packaged_task;
229 typedef std::future<bool> future;
230 typedef std::shared_future<bool> shared_future;
231
232 typedef std::thread thread;
233
234 static const milliseconds waitDur;
235
236 template <typename T>
237 static void sleep_for(T d)
238 {
239 std::this_thread::sleep_for(d);
240 }
241
242 template <typename T>
243 static void sleep_until(T t)
244 {
245 std::this_thread::sleep_until(t);
246 }
247
248 static system_time_point systemNow()
249 {
250 return system_clock::now();
251 }
252
253 static steady_time_point steadyNow()
254 {
255 return steady_clock::now();
256 }
257
258 static custom_time_point customNow()
259 {
260 return custom_clock::now();
261 }
262
263 template <class ToDuration, class Rep, class Period>
264 static ToDuration duration_cast(const std::chrono::duration<Rep, Period>& d)
265 {
266 return std::chrono::duration_cast<ToDuration>(d);
267 }
268
269 static milliseconds zero()
270 {
271 return milliseconds(0);
272 }
273 };
274
275 template <typename MutexType, typename CondType>
276 const typename StdHelper<MutexType, CondType>::milliseconds
277 StdHelper<MutexType, CondType>::waitDur = typename StdHelper<MutexType, CondType>::milliseconds(s_waitMs);
278 #endif
279
280 /******************************************************************************/
281
282 #ifdef _WIN32
283
284 void changeSystemTime(long long changeMs)
285 {
286 Sleep(s_sleepBeforeJumpMs);
287
288 SYSTEMTIME systemTime;
289 GetSystemTime(&systemTime);
290
291 FILETIME fileTime;
292 if (!SystemTimeToFileTime(&systemTime, &fileTime))
293 {
294 std::cout << "ERROR: Couldn't convert system time to file time" << std::endl;
295 }
296
297 ULARGE_INTEGER largeInt;
298 largeInt.LowPart = fileTime.dwLowDateTime;
299 largeInt.HighPart = fileTime.dwHighDateTime;
300 largeInt.QuadPart += changeMs * 10000;
301 fileTime.dwLowDateTime = largeInt.LowPart;
302 fileTime.dwHighDateTime = largeInt.HighPart;
303
304 if (!FileTimeToSystemTime(&fileTime, &systemTime))
305 {
306 std::cout << "ERROR: Couldn't convert file time to system time" << std::endl;
307 }
308
309 if (!SetSystemTime(&systemTime))
310 {
311 std::cout << "ERROR: Couldn't set system time" << std::endl;
312 }
313 }
314
315 #else
316
317 void changeSystemTime(long long changeMs)
318 {
319 struct timespec sleepTs;
320 sleepTs.tv_sec = (s_sleepBeforeJumpMs / 1000);
321 sleepTs.tv_nsec = (s_sleepBeforeJumpMs % 1000) * 1000000;
322 nanosleep(&sleepTs, NULL);
323
324 struct timeval tv;
325 if (gettimeofday(&tv, NULL) != 0)
326 {
327 std::cout << "ERROR: Couldn't get system time" << std::endl;
328 }
329
330 changeMs += tv.tv_sec * 1000;
331 changeMs += tv.tv_usec / 1000;
332 tv.tv_sec = (changeMs / 1000);
333 tv.tv_usec = (changeMs % 1000) * 1000;
334
335 if (settimeofday(&tv, NULL) != 0)
336 {
337 std::cout << "ERROR: Couldn't set system time" << std::endl;
338 }
339 }
340
341 #endif
342
343 enum RcEnum
344 {
345 e_no_timeout,
346 e_timeout,
347 e_failed_bad,
348 e_failed_good,
349 e_succeeded_bad,
350 e_succeeded_good,
351 e_ready_bad,
352 e_not_ready_good,
353 e_na
354 };
355
356 template <typename Helper>
357 void checkWaitTime(typename Helper::nanoseconds expected, typename Helper::nanoseconds actual, RcEnum rc)
358 {
359 if (expected != Helper::zero() && expected < typename Helper::milliseconds(s_sleepBeforeJumpMs))
360 {
361 expected = typename Helper::milliseconds(s_sleepBeforeJumpMs);
362 }
363
364 typename Helper::milliseconds expectedMs = Helper::template duration_cast<typename Helper::milliseconds>(expected);
365 typename Helper::milliseconds actualMs = Helper::template duration_cast<typename Helper::milliseconds>(actual);
366
367 std::cout << "Expected: " << std::setw(4) << expectedMs.count() << " ms"
368 << ", Actual: " << std::setw(4) << actualMs.count() << " ms"
369 << ", Returned: ";
370 switch (rc)
371 {
372 case e_no_timeout : std::cout << "no_timeout, "; break;
373 case e_timeout : std::cout << "timeout, "; break;
374 case e_failed_bad : std::cout << "failed, "; break;
375 case e_failed_good : std::cout << "failed, "; break;
376 case e_succeeded_bad : std::cout << "succeeded, "; break;
377 case e_succeeded_good : std::cout << "succeeded, "; break;
378 case e_ready_bad : std::cout << "ready, "; break;
379 case e_not_ready_good : std::cout << "not_ready, "; break;
380 default : std::cout << "N/A, "; break;
381 }
382
383 if (expectedMs == Helper::zero())
384 {
385 std::cout << "FAILED: SKIPPED (test would lock up if run)";
386 g_numTestsFailed++;
387 }
388 else if (actual < expected - typename Helper::milliseconds(s_maxEarlyErrorMs))
389 {
390 std::cout << "FAILED: TOO SHORT";
391 if (rc == e_timeout) // bad
392 {
393 std::cout << ", RETURNED TIMEOUT";
394 }
395 else if (rc == e_failed_bad)
396 {
397 std::cout << ", RETURNED FAILED";
398 }
399 else if (rc == e_succeeded_bad)
400 {
401 std::cout << ", RETURNED SUCCEEDED";
402 }
403 else if (rc == e_ready_bad)
404 {
405 std::cout << ", RETURNED READY";
406 }
407 g_numTestsFailed++;
408 }
409 else if (actual > expected + typename Helper::milliseconds(s_maxLateErrorMs))
410 {
411 std::cout << "FAILED: TOO LONG";
412 if (rc == e_no_timeout) // bad
413 {
414 std::cout << ", RETURNED NO_TIMEOUT";
415 }
416 else if (rc == e_failed_bad)
417 {
418 std::cout << ", RETURNED FAILED";
419 }
420 else if (rc == e_succeeded_bad)
421 {
422 std::cout << ", RETURNED SUCCEEDED";
423 }
424 else if (rc == e_ready_bad)
425 {
426 std::cout << ", RETURNED READY";
427 }
428 g_numTestsFailed++;
429 }
430 else if (rc == e_no_timeout) // bad
431 {
432 std::cout << "FAILED: RETURNED NO_TIMEOUT";
433 g_numTestsFailed++;
434 }
435 else if (rc == e_failed_bad)
436 {
437 std::cout << "FAILED: RETURNED FAILED";
438 g_numTestsFailed++;
439 }
440 else if (rc == e_succeeded_bad)
441 {
442 std::cout << "FAILED: RETURNED SUCCEEDED";
443 g_numTestsFailed++;
444 }
445 else if (rc == e_ready_bad)
446 {
447 std::cout << "FAILED: RETURNED READY";
448 g_numTestsFailed++;
449 }
450 else
451 {
452 std::cout << "Passed";
453 g_numTestsPassed++;
454 }
455 std::cout << std::endl;
456
457 g_numTestsRun++;
458 }
459
460 void sleepForLongTime()
461 {
462 #ifdef _WIN32
463 Sleep(10000);
464 #else
465 struct timespec ts = {5, 0};
466 nanosleep(&ts, NULL);
467 #endif
468 }
469
470 bool returnFalse()
471 {
472 return false;
473 }
474
475 /******************************************************************************/
476
477 // Run the test in the context provided, which may be the current thread or a separate thread.
478 template <typename Helper, typename Context, typename Function>
479 void runTestInContext(Context context, Function func, const std::string name)
480 {
481 std::cout << name << ":" << std::endl;
482
483 {
484 std::cout << " While system clock remains stable: ";
485 context(func, 0);
486 }
487
488 {
489 std::cout << " While system clock jumps back (short): ";
490 typename Helper::thread t(boost::bind(changeSystemTime, -s_shortJumpMs));
491 context(func, -s_shortJumpMs);
492 t.join();
493 }
494
495 {
496 std::cout << " While system clock jumps back (long): ";
497 typename Helper::thread t(boost::bind(changeSystemTime, -s_longJumpMs));
498 context(func, -s_longJumpMs);
499 t.join();
500 }
501
502 {
503 std::cout << " While system clock jumps forward (short): ";
504 typename Helper::thread t(boost::bind(changeSystemTime, s_shortJumpMs));
505 context(func, s_shortJumpMs);
506 t.join();
507 }
508
509 {
510 std::cout << " While system clock jumps forward (long): ";
511 typename Helper::thread t(boost::bind(changeSystemTime, s_longJumpMs));
512 context(func, s_longJumpMs);
513 t.join();
514 }
515 }
516
517 //--------------------------------------
518
519 template <typename Helper, typename Function>
520 void noThreadContext(Function func, const long long jumpMs)
521 {
522 func(jumpMs);
523 }
524
525 template <typename Helper, typename Function>
526 void threadContextWithNone(Function func, const long long jumpMs)
527 {
528 typename Helper::thread t(boost::bind(func, jumpMs));
529 t.join();
530 }
531
532 template <typename Helper, typename Function>
533 void threadContextWithUnique(Function func, const long long jumpMs)
534 {
535 typename Helper::mutex m;
536 typename Helper::lock_guard g(m);
537 typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
538 t.join();
539 }
540
541 template <typename Helper, typename Function>
542 void threadContextWithShared(Function func, const long long jumpMs)
543 {
544 typename Helper::mutex m;
545 boost::shared_lock_guard<typename Helper::mutex> g(m);
546 typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
547 t.join();
548 }
549
550 template <typename Helper, typename Function>
551 void threadContextWithUpgrade(Function func, const long long jumpMs)
552 {
553 typename Helper::mutex m;
554 boost::upgrade_lock<typename Helper::mutex> g(m);
555 typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs));
556 t.join();
557 }
558
559 //--------------------------------------
560
561 // Run the test in the current thread.
562 template <typename Helper, typename Function>
563 void runTest(Function func, const std::string name)
564 {
565 runTestInContext<Helper>(noThreadContext<Helper, Function>, func, name);
566 }
567
568 // Run the test in a separate thread.
569 template <typename Helper, typename Function>
570 void runTestWithNone(Function func, const std::string name)
571 {
572 runTestInContext<Helper>(threadContextWithNone<Helper, Function>, func, name);
573 }
574
575 // Run the test in a separate thread. Pass a locked mutex to the function under test.
576 template <typename Helper, typename Function>
577 void runTestWithUnique(Function func, const std::string name)
578 {
579 runTestInContext<Helper>(threadContextWithUnique<Helper, Function>, func, name);
580 }
581
582 // Run the test in a separate thread. Pass a shared-locked mutex to the function under test.
583 template <typename Helper, typename Function>
584 void runTestWithShared(Function func, const std::string name)
585 {
586 runTestInContext<Helper>(threadContextWithShared<Helper, Function>, func, name);
587 }
588
589 // Run the test in a separate thread. Pass an upgrade-locked mutex to the function under test.
590 template <typename Helper, typename Function>
591 void runTestWithUpgrade(Function func, const std::string name)
592 {
593 runTestInContext<Helper>(threadContextWithUpgrade<Helper, Function>, func, name);
594 }
595
596 /******************************************************************************/
597
598 // Test Sleep
599
600 template <typename Helper>
601 void testSleepFor(const long long jumpMs)
602 {
603 typename Helper::steady_time_point before(Helper::steadyNow());
604 Helper::sleep_for(Helper::waitDur);
605 typename Helper::steady_time_point after(Helper::steadyNow());
606
607 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
608 }
609
610 template <typename Helper>
611 void testSleepUntilSteady(const long long jumpMs)
612 {
613 typename Helper::steady_time_point before(Helper::steadyNow());
614 Helper::sleep_until(Helper::steadyNow() + Helper::waitDur);
615 typename Helper::steady_time_point after(Helper::steadyNow());
616
617 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
618 }
619
620 template <typename Helper>
621 void testSleepUntilSystem(const long long jumpMs)
622 {
623 typename Helper::steady_time_point before(Helper::steadyNow());
624 Helper::sleep_until(Helper::systemNow() + Helper::waitDur);
625 typename Helper::steady_time_point after(Helper::steadyNow());
626
627 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
628 }
629
630 template <typename Helper>
631 void testSleepUntilCustom(const long long jumpMs)
632 {
633 typename Helper::steady_time_point before(Helper::steadyNow());
634 Helper::sleep_until(Helper::customNow() + Helper::waitDur);
635 typename Helper::steady_time_point after(Helper::steadyNow());
636
637 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
638 }
639
640 //--------------------------------------
641
642 template <typename Helper>
643 void testSleepRelative(const long long jumpMs)
644 {
645 #ifndef SKIP_DATETIME_FUNCTIONS
646 typename Helper::steady_time_point before(Helper::steadyNow());
647 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
648 boost::this_thread::sleep(ptDur);
649 typename Helper::steady_time_point after(Helper::steadyNow());
650
651 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
652 #else
653 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
654 #endif
655 }
656
657 template <typename Helper>
658 void testSleepAbsolute(const long long jumpMs)
659 {
660 #ifndef SKIP_DATETIME_FUNCTIONS
661 typename Helper::steady_time_point before(Helper::steadyNow());
662 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
663 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
664 boost::this_thread::sleep(ptNow + ptDur);
665 typename Helper::steady_time_point after(Helper::steadyNow());
666
667 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
668 #else
669 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
670 #endif
671 }
672
673 //--------------------------------------
674
675 template <typename Helper>
676 void testSleepStd(const std::string& name)
677 {
678 std::cout << std::endl;
679 runTestWithNone<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for()");
680 runTestWithNone<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), steady time");
681 runTestWithNone<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), system time");
682 runTestWithNone<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), custom time");
683 }
684
685 template <typename Helper>
686 void testSleepBoost(const std::string& name)
687 {
688 testSleepStd<Helper>(name);
689
690 // Boost-only functions
691 runTestWithNone<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), relative time");
692 runTestWithNone<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), absolute time");
693 }
694
695 template <typename Helper>
696 void testSleepNoThreadStd(const std::string& name)
697 {
698 std::cout << std::endl;
699 runTest<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for(), no thread");
700 runTest<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), no thread, steady time");
701 runTest<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), no thread, system time");
702 runTest<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), no thread, custom time");
703 }
704
705 template <typename Helper>
706 void testSleepNoThreadBoost(const std::string& name)
707 {
708 testSleepNoThreadStd<Helper>(name);
709
710 // Boost-only functions
711 runTest<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), no thread, relative time");
712 runTest<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), no thread, absolute time");
713 }
714
715 /******************************************************************************/
716
717 // Test Sleep, No Interruption Point
718
719 template <typename Helper>
720 void testSleepForNoInt(const long long jumpMs)
721 {
722 typename Helper::steady_time_point before(Helper::steadyNow());
723 Helper::sleep_for_no_int(Helper::waitDur);
724 typename Helper::steady_time_point after(Helper::steadyNow());
725
726 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
727 }
728
729 template <typename Helper>
730 void testSleepUntilNoIntSteady(const long long jumpMs)
731 {
732 typename Helper::steady_time_point before(Helper::steadyNow());
733 Helper::sleep_until_no_int(Helper::steadyNow() + Helper::waitDur);
734 typename Helper::steady_time_point after(Helper::steadyNow());
735
736 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
737 }
738
739 template <typename Helper>
740 void testSleepUntilNoIntSystem(const long long jumpMs)
741 {
742 typename Helper::steady_time_point before(Helper::steadyNow());
743 Helper::sleep_until_no_int(Helper::systemNow() + Helper::waitDur);
744 typename Helper::steady_time_point after(Helper::steadyNow());
745
746 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
747 }
748
749 template <typename Helper>
750 void testSleepUntilNoIntCustom(const long long jumpMs)
751 {
752 typename Helper::steady_time_point before(Helper::steadyNow());
753 Helper::sleep_until_no_int(Helper::customNow() + Helper::waitDur);
754 typename Helper::steady_time_point after(Helper::steadyNow());
755
756 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
757 }
758
759 //--------------------------------------
760
761 #ifndef SKIP_NO_INT_SLEEP
762
763 template <typename Helper>
764 void testSleepNoIntRelative(const long long jumpMs)
765 {
766 #ifndef SKIP_DATETIME_FUNCTIONS
767 typename Helper::steady_time_point before(Helper::steadyNow());
768 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
769 boost::this_thread::no_interruption_point::sleep(ptDur);
770 typename Helper::steady_time_point after(Helper::steadyNow());
771
772 checkWaitTime<Helper>(Helper::waitDur, after - before, e_na);
773 #else
774 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
775 #endif
776 }
777
778 template <typename Helper>
779 void testSleepNoIntAbsolute(const long long jumpMs)
780 {
781 #ifndef SKIP_DATETIME_FUNCTIONS
782 typename Helper::steady_time_point before(Helper::steadyNow());
783 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
784 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
785 boost::this_thread::no_interruption_point::sleep(ptNow + ptDur);
786 typename Helper::steady_time_point after(Helper::steadyNow());
787
788 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na);
789 #else
790 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
791 #endif
792 }
793
794 #endif
795
796 //--------------------------------------
797
798 // Only Boost supports no_interruption_point
799
800 template <typename Helper>
801 void testSleepNoIntBoost(const std::string& name)
802 {
803 std::cout << std::endl;
804 runTestWithNone<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for()");
805 runTestWithNone<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), steady time");
806 runTestWithNone<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), system time");
807 runTestWithNone<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), custom time");
808
809 #ifndef SKIP_NO_INT_SLEEP
810 runTestWithNone<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), relative time");
811 runTestWithNone<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), absolute time");
812 #endif
813 }
814
815 template <typename Helper>
816 void testSleepNoThreadNoIntBoost(const std::string& name)
817 {
818 std::cout << std::endl;
819 runTest<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for(), no thread");
820 runTest<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, steady time");
821 runTest<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, system time");
822 runTest<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, custom time");
823
824 #ifndef SKIP_NO_INT_SLEEP
825 runTest<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, relative time");
826 runTest<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, absolute time");
827 #endif
828 }
829
830 /******************************************************************************/
831
832 // Test Try Join
833
834 template <typename Helper>
835 void testTryJoinFor(const long long jumpMs)
836 {
837 typename Helper::steady_time_point before(Helper::steadyNow());
838 typename Helper::thread t3(sleepForLongTime);
839 bool succeeded = t3.try_join_for(Helper::waitDur);
840 typename Helper::steady_time_point after(Helper::steadyNow());
841
842 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
843 }
844
845 template <typename Helper>
846 void testTryJoinUntilSteady(const long long jumpMs)
847 {
848 typename Helper::steady_time_point before(Helper::steadyNow());
849 typename Helper::thread t3(sleepForLongTime);
850 bool succeeded = t3.try_join_until(Helper::steadyNow() + Helper::waitDur);
851 typename Helper::steady_time_point after(Helper::steadyNow());
852
853 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
854 }
855
856 template <typename Helper>
857 void testTryJoinUntilSystem(const long long jumpMs)
858 {
859 typename Helper::steady_time_point before(Helper::steadyNow());
860 typename Helper::thread t3(sleepForLongTime);
861 bool succeeded = t3.try_join_until(Helper::systemNow() + Helper::waitDur);
862 typename Helper::steady_time_point after(Helper::steadyNow());
863
864 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
865 }
866
867 template <typename Helper>
868 void testTryJoinUntilCustom(const long long jumpMs)
869 {
870 typename Helper::steady_time_point before(Helper::steadyNow());
871 typename Helper::thread t3(sleepForLongTime);
872 bool succeeded = t3.try_join_until(Helper::customNow() + Helper::waitDur);
873 typename Helper::steady_time_point after(Helper::steadyNow());
874
875 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
876 }
877
878 //--------------------------------------
879
880 template <typename Helper>
881 void testTimedJoinRelative(const long long jumpMs)
882 {
883 #ifndef SKIP_DATETIME_FUNCTIONS
884 typename Helper::steady_time_point before(Helper::steadyNow());
885 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
886 typename Helper::thread t3(sleepForLongTime);
887 bool succeeded = t3.timed_join(ptDur);
888 typename Helper::steady_time_point after(Helper::steadyNow());
889
890 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
891 #else
892 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
893 #endif
894 }
895
896 template <typename Helper>
897 void testTimedJoinAbsolute(const long long jumpMs)
898 {
899 #ifndef SKIP_DATETIME_FUNCTIONS
900 typename Helper::steady_time_point before(Helper::steadyNow());
901 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
902 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
903 typename Helper::thread t3(sleepForLongTime);
904 bool succeeded = t3.timed_join(ptNow + ptDur);
905 typename Helper::steady_time_point after(Helper::steadyNow());
906
907 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
908 #else
909 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
910 #endif
911 }
912
913 //--------------------------------------
914
915 // Only Boost supports timed try_join functions
916
917 template <typename Helper>
918 void testJoinBoost(const std::string& name)
919 {
920 std::cout << std::endl;
921 runTestWithNone<Helper>(testTryJoinFor <Helper>, name + "::thread::try_join_for()");
922 runTestWithNone<Helper>(testTryJoinUntilSteady<Helper>, name + "::thread::try_join_until(), steady time");
923 runTestWithNone<Helper>(testTryJoinUntilSystem<Helper>, name + "::thread::try_join_until(), system time");
924 runTestWithNone<Helper>(testTryJoinUntilCustom<Helper>, name + "::thread::try_join_until(), custom time");
925 runTestWithNone<Helper>(testTimedJoinRelative <Helper>, name + "::thread::timed_join(), relative time");
926 runTestWithNone<Helper>(testTimedJoinAbsolute <Helper>, name + "::thread::timed_join(), absolute time");
927 }
928
929 /******************************************************************************/
930
931 // Test Condition Variable Wait
932
933 template <typename Helper>
934 void testCondVarWaitFor(const long long jumpMs)
935 {
936 typename Helper::cond cv;
937 typename Helper::mutex m;
938 typename Helper::unique_lock g(m);
939
940 typename Helper::steady_time_point before(Helper::steadyNow());
941 bool noTimeout = (cv.wait_for(g, Helper::waitDur) == Helper::cv_status::no_timeout);
942 typename Helper::steady_time_point after(Helper::steadyNow());
943
944 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
945 }
946
947 template <typename Helper>
948 void testCondVarWaitUntilSteady(const long long jumpMs)
949 {
950 typename Helper::cond cv;
951 typename Helper::mutex m;
952 typename Helper::unique_lock g(m);
953
954 typename Helper::steady_time_point before(Helper::steadyNow());
955 bool noTimeout = (cv.wait_until(g, Helper::steadyNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
956 typename Helper::steady_time_point after(Helper::steadyNow());
957
958 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
959 }
960
961 template <typename Helper>
962 void testCondVarWaitUntilSystem(const long long jumpMs)
963 {
964 typename Helper::cond cv;
965 typename Helper::mutex m;
966 typename Helper::unique_lock g(m);
967
968 typename Helper::steady_time_point before(Helper::steadyNow());
969 bool noTimeout = (cv.wait_until(g, Helper::systemNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
970 typename Helper::steady_time_point after(Helper::steadyNow());
971
972 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
973 }
974
975 template <typename Helper>
976 void testCondVarWaitUntilCustom(const long long jumpMs)
977 {
978 typename Helper::cond cv;
979 typename Helper::mutex m;
980 typename Helper::unique_lock g(m);
981
982 typename Helper::steady_time_point before(Helper::steadyNow());
983 bool noTimeout = (cv.wait_until(g, Helper::customNow() + Helper::waitDur) == Helper::cv_status::no_timeout);
984 typename Helper::steady_time_point after(Helper::steadyNow());
985
986 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
987 }
988
989 //--------------------------------------
990
991 template <typename Helper>
992 void testCondVarTimedWaitRelative(const long long jumpMs)
993 {
994 #ifndef SKIP_DATETIME_FUNCTIONS
995 typename Helper::cond cv;
996 typename Helper::mutex m;
997 typename Helper::unique_lock g(m);
998
999 typename Helper::steady_time_point before(Helper::steadyNow());
1000 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1001 bool noTimeout = cv.timed_wait(g, ptDur);
1002 typename Helper::steady_time_point after(Helper::steadyNow());
1003
1004 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1005 #else
1006 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1007 #endif
1008 }
1009
1010 template <typename Helper>
1011 void testCondVarTimedWaitAbsolute(const long long jumpMs)
1012 {
1013 #ifndef SKIP_DATETIME_FUNCTIONS
1014 typename Helper::cond cv;
1015 typename Helper::mutex m;
1016 typename Helper::unique_lock g(m);
1017
1018 typename Helper::steady_time_point before(Helper::steadyNow());
1019 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1020 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1021 bool noTimeout = cv.timed_wait(g, ptNow + ptDur);
1022 typename Helper::steady_time_point after(Helper::steadyNow());
1023
1024 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1025 #else
1026 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1027 #endif
1028 }
1029
1030 //--------------------------------------
1031
1032 template <typename Helper>
1033 void testCondVarStd(const std::string& name)
1034 {
1035 std::cout << std::endl;
1036 runTestWithNone<Helper>(testCondVarWaitFor <Helper>, name + "::wait_for()");
1037 runTestWithNone<Helper>(testCondVarWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
1038 runTestWithNone<Helper>(testCondVarWaitUntilSystem<Helper>, name + "::wait_until(), system time");
1039 runTestWithNone<Helper>(testCondVarWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
1040 }
1041
1042 template <typename Helper>
1043 void testCondVarBoost(const std::string& name)
1044 {
1045 testCondVarStd<Helper>(name);
1046
1047 // Boost-only functions
1048 runTestWithNone<Helper>(testCondVarTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
1049 runTestWithNone<Helper>(testCondVarTimedWaitAbsolute<Helper>, name + "::timed_wait(), absolute time");
1050 }
1051
1052 /******************************************************************************/
1053
1054 // Test Condition Variable Wait with Predicate
1055
1056 template <typename Helper>
1057 void testCondVarWaitForPred(const long long jumpMs)
1058 {
1059 typename Helper::cond cv;
1060 typename Helper::mutex m;
1061 typename Helper::unique_lock g(m);
1062
1063 typename Helper::steady_time_point before(Helper::steadyNow());
1064 bool noTimeout = cv.wait_for(g, Helper::waitDur, returnFalse);
1065 typename Helper::steady_time_point after(Helper::steadyNow());
1066
1067 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1068 }
1069
1070 template <typename Helper>
1071 void testCondVarWaitUntilPredSteady(const long long jumpMs)
1072 {
1073 typename Helper::cond cv;
1074 typename Helper::mutex m;
1075 typename Helper::unique_lock g(m);
1076
1077 typename Helper::steady_time_point before(Helper::steadyNow());
1078 bool noTimeout = cv.wait_until(g, Helper::steadyNow() + Helper::waitDur, returnFalse);
1079 typename Helper::steady_time_point after(Helper::steadyNow());
1080
1081 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1082 }
1083
1084 template <typename Helper>
1085 void testCondVarWaitUntilPredSystem(const long long jumpMs)
1086 {
1087 typename Helper::cond cv;
1088 typename Helper::mutex m;
1089 typename Helper::unique_lock g(m);
1090
1091 typename Helper::steady_time_point before(Helper::steadyNow());
1092 bool noTimeout = cv.wait_until(g, Helper::systemNow() + Helper::waitDur, returnFalse);
1093 typename Helper::steady_time_point after(Helper::steadyNow());
1094
1095 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1096 }
1097
1098 template <typename Helper>
1099 void testCondVarWaitUntilPredCustom(const long long jumpMs)
1100 {
1101 typename Helper::cond cv;
1102 typename Helper::mutex m;
1103 typename Helper::unique_lock g(m);
1104
1105 typename Helper::steady_time_point before(Helper::steadyNow());
1106 bool noTimeout = cv.wait_until(g, Helper::customNow() + Helper::waitDur, returnFalse);
1107 typename Helper::steady_time_point after(Helper::steadyNow());
1108
1109 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1110 }
1111
1112 //--------------------------------------
1113
1114 template <typename Helper>
1115 void testCondVarTimedWaitPredRelative(const long long jumpMs)
1116 {
1117 #ifndef SKIP_DATETIME_FUNCTIONS
1118 typename Helper::cond cv;
1119 typename Helper::mutex m;
1120 typename Helper::unique_lock g(m);
1121
1122 typename Helper::steady_time_point before(Helper::steadyNow());
1123 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1124 bool noTimeout = cv.timed_wait(g, ptDur, returnFalse);
1125 typename Helper::steady_time_point after(Helper::steadyNow());
1126
1127 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1128 #else
1129 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1130 #endif
1131 }
1132
1133 template <typename Helper>
1134 void testCondVarTimedWaitPredAbsolute(const long long jumpMs)
1135 {
1136 #ifndef SKIP_DATETIME_FUNCTIONS
1137 typename Helper::cond cv;
1138 typename Helper::mutex m;
1139 typename Helper::unique_lock g(m);
1140
1141 typename Helper::steady_time_point before(Helper::steadyNow());
1142 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1143 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1144 bool noTimeout = cv.timed_wait(g, ptNow + ptDur, returnFalse);
1145 typename Helper::steady_time_point after(Helper::steadyNow());
1146
1147 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1148 #else
1149 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1150 #endif
1151 }
1152
1153 //--------------------------------------
1154
1155 template <typename Helper>
1156 void testCondVarPredStd(const std::string& name)
1157 {
1158 std::cout << std::endl;
1159 runTestWithNone<Helper>(testCondVarWaitForPred <Helper>, name + "::wait_for(), with predicate");
1160 runTestWithNone<Helper>(testCondVarWaitUntilPredSteady<Helper>, name + "::wait_until(), with predicate, steady time");
1161 runTestWithNone<Helper>(testCondVarWaitUntilPredSystem<Helper>, name + "::wait_until(), with predicate, system time");
1162 runTestWithNone<Helper>(testCondVarWaitUntilPredCustom<Helper>, name + "::wait_until(), with predicate, custom time");
1163 }
1164
1165 template <typename Helper>
1166 void testCondVarPredBoost(const std::string& name)
1167 {
1168 testCondVarPredStd<Helper>(name);
1169
1170 // Boost-only functions
1171 runTestWithNone<Helper>(testCondVarTimedWaitPredRelative<Helper>, name + "::timed_wait(), with predicate, relative time");
1172 runTestWithNone<Helper>(testCondVarTimedWaitPredAbsolute<Helper>, name + "::timed_wait(), with predicate, absolute time");
1173 }
1174
1175 /******************************************************************************/
1176
1177 // Test Try Lock
1178
1179 template <typename Helper>
1180 void testTryLockFor(typename Helper::mutex& m, const long long jumpMs)
1181 {
1182 typename Helper::steady_time_point before(Helper::steadyNow());
1183 bool succeeded = m.try_lock_for(Helper::waitDur);
1184 typename Helper::steady_time_point after(Helper::steadyNow());
1185
1186 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1187 }
1188
1189 template <typename Helper>
1190 void testTryLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1191 {
1192 typename Helper::steady_time_point before(Helper::steadyNow());
1193 bool succeeded = m.try_lock_until(Helper::steadyNow() + Helper::waitDur);
1194 typename Helper::steady_time_point after(Helper::steadyNow());
1195
1196 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1197 }
1198
1199 template <typename Helper>
1200 void testTryLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1201 {
1202 typename Helper::steady_time_point before(Helper::steadyNow());
1203 bool succeeded = m.try_lock_until(Helper::systemNow() + Helper::waitDur);
1204 typename Helper::steady_time_point after(Helper::steadyNow());
1205
1206 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1207 }
1208
1209 template <typename Helper>
1210 void testTryLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1211 {
1212 typename Helper::steady_time_point before(Helper::steadyNow());
1213 bool succeeded = m.try_lock_until(Helper::customNow() + Helper::waitDur);
1214 typename Helper::steady_time_point after(Helper::steadyNow());
1215
1216 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1217 }
1218
1219 //--------------------------------------
1220
1221 template <typename Helper>
1222 void testTimedLockRelative(typename Helper::mutex& m, const long long jumpMs)
1223 {
1224 #ifndef SKIP_DATETIME_FUNCTIONS
1225 typename Helper::steady_time_point before(Helper::steadyNow());
1226 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1227 bool succeeded = m.timed_lock(ptDur);
1228 typename Helper::steady_time_point after(Helper::steadyNow());
1229
1230 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1231 #else
1232 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1233 #endif
1234 }
1235
1236 template <typename Helper>
1237 void testTimedLockAbsolute(typename Helper::mutex& m, const long long jumpMs)
1238 {
1239 #ifndef SKIP_DATETIME_FUNCTIONS
1240 typename Helper::steady_time_point before(Helper::steadyNow());
1241 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1242 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1243 bool succeeded = m.timed_lock(ptNow + ptDur);
1244 typename Helper::steady_time_point after(Helper::steadyNow());
1245
1246 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1247 #else
1248 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1249 #endif
1250 }
1251
1252 //--------------------------------------
1253
1254 template <typename Helper>
1255 void testMutexStd(const std::string& name)
1256 {
1257 std::cout << std::endl;
1258 runTestWithUnique<Helper>(testTryLockFor <Helper>, name + "::try_lock_for()");
1259 runTestWithUnique<Helper>(testTryLockUntilSteady<Helper>, name + "::try_lock_until(), steady time");
1260 runTestWithUnique<Helper>(testTryLockUntilSystem<Helper>, name + "::try_lock_until(), system time");
1261 runTestWithUnique<Helper>(testTryLockUntilCustom<Helper>, name + "::try_lock_until(), custom time");
1262 }
1263
1264 template <typename Helper>
1265 void testMutexBoost(const std::string& name)
1266 {
1267 testMutexStd<Helper>(name);
1268
1269 // Boost-only functions
1270 runTestWithUnique<Helper>(testTimedLockRelative<Helper>, name + "::timed_lock(), relative time");
1271 runTestWithUnique<Helper>(testTimedLockAbsolute<Helper>, name + "::timed_lock(), absolute time");
1272 }
1273
1274 /******************************************************************************/
1275
1276 // Test Try Lock Shared
1277
1278 template <typename Helper>
1279 void testTryLockSharedFor(typename Helper::mutex& m, const long long jumpMs)
1280 {
1281 typename Helper::steady_time_point before(Helper::steadyNow());
1282 bool succeeded = m.try_lock_shared_for(Helper::waitDur);
1283 typename Helper::steady_time_point after(Helper::steadyNow());
1284
1285 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1286 }
1287
1288 template <typename Helper>
1289 void testTryLockSharedUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1290 {
1291 typename Helper::steady_time_point before(Helper::steadyNow());
1292 bool succeeded = m.try_lock_shared_until(Helper::steadyNow() + Helper::waitDur);
1293 typename Helper::steady_time_point after(Helper::steadyNow());
1294
1295 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1296 }
1297
1298 template <typename Helper>
1299 void testTryLockSharedUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1300 {
1301 typename Helper::steady_time_point before(Helper::steadyNow());
1302 bool succeeded = m.try_lock_shared_until(Helper::systemNow() + Helper::waitDur);
1303 typename Helper::steady_time_point after(Helper::steadyNow());
1304
1305 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1306 }
1307
1308 template <typename Helper>
1309 void testTryLockSharedUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1310 {
1311 typename Helper::steady_time_point before(Helper::steadyNow());
1312 bool succeeded = m.try_lock_shared_until(Helper::customNow() + Helper::waitDur);
1313 typename Helper::steady_time_point after(Helper::steadyNow());
1314
1315 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1316 }
1317
1318 //--------------------------------------
1319
1320 template <typename Helper>
1321 void testTimedLockSharedRelative(typename Helper::mutex& m, const long long jumpMs)
1322 {
1323 #ifndef SKIP_DATETIME_FUNCTIONS
1324 typename Helper::steady_time_point before(Helper::steadyNow());
1325 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1326 bool succeeded = m.timed_lock_shared(ptDur);
1327 typename Helper::steady_time_point after(Helper::steadyNow());
1328
1329 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1330 #else
1331 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1332 #endif
1333 }
1334
1335 template <typename Helper>
1336 void testTimedLockSharedAbsolute(typename Helper::mutex& m, const long long jumpMs)
1337 {
1338 #ifndef SKIP_DATETIME_FUNCTIONS
1339 typename Helper::steady_time_point before(Helper::steadyNow());
1340 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1341 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1342 bool succeeded = m.timed_lock_shared(ptNow + ptDur);
1343 typename Helper::steady_time_point after(Helper::steadyNow());
1344
1345 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1346 #else
1347 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1348 #endif
1349 }
1350
1351 //--------------------------------------
1352
1353 template <typename Helper>
1354 void testMutexSharedStd(const std::string& name)
1355 {
1356 std::cout << std::endl;
1357 runTestWithUnique<Helper>(testTryLockSharedFor <Helper>, name + "::try_lock_shared_for()");
1358 runTestWithUnique<Helper>(testTryLockSharedUntilSteady<Helper>, name + "::try_lock_shared_until(), steady time");
1359 runTestWithUnique<Helper>(testTryLockSharedUntilSystem<Helper>, name + "::try_lock_shared_until(), system time");
1360 runTestWithUnique<Helper>(testTryLockSharedUntilCustom<Helper>, name + "::try_lock_shared_until(), custom time");
1361 }
1362
1363 template <typename Helper>
1364 void testMutexSharedBoost(const std::string& name)
1365 {
1366 testMutexSharedStd<Helper>(name);
1367
1368 // Boost-only functions
1369 runTestWithUnique<Helper>(testTimedLockSharedRelative<Helper>, name + "::timed_lock_shared(), relative time");
1370 runTestWithUnique<Helper>(testTimedLockSharedAbsolute<Helper>, name + "::timed_lock_shared(), absolute time");
1371 }
1372
1373 /******************************************************************************/
1374
1375 // Test Try Lock Upgrade
1376
1377 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
1378
1379 template <typename Helper>
1380 void testTryLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs)
1381 {
1382 typename Helper::steady_time_point before(Helper::steadyNow());
1383 bool succeeded = m.try_lock_upgrade_for(Helper::waitDur);
1384 typename Helper::steady_time_point after(Helper::steadyNow());
1385
1386 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1387 }
1388
1389 template <typename Helper>
1390 void testTryLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1391 {
1392 typename Helper::steady_time_point before(Helper::steadyNow());
1393 bool succeeded = m.try_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur);
1394 typename Helper::steady_time_point after(Helper::steadyNow());
1395
1396 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1397 }
1398
1399 template <typename Helper>
1400 void testTryLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1401 {
1402 typename Helper::steady_time_point before(Helper::steadyNow());
1403 bool succeeded = m.try_lock_upgrade_until(Helper::systemNow() + Helper::waitDur);
1404 typename Helper::steady_time_point after(Helper::steadyNow());
1405
1406 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1407 }
1408
1409 template <typename Helper>
1410 void testTryLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1411 {
1412 typename Helper::steady_time_point before(Helper::steadyNow());
1413 bool succeeded = m.try_lock_upgrade_until(Helper::customNow() + Helper::waitDur);
1414 typename Helper::steady_time_point after(Helper::steadyNow());
1415
1416 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1417 }
1418
1419 //--------------------------------------
1420
1421 template <typename Helper>
1422 void testTimedLockUpgradeRelative(typename Helper::mutex& m, const long long jumpMs)
1423 {
1424 #ifndef SKIP_DATETIME_FUNCTIONS
1425 typename Helper::steady_time_point before(Helper::steadyNow());
1426 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1427 bool succeeded = m.timed_lock_upgrade(ptDur);
1428 typename Helper::steady_time_point after(Helper::steadyNow());
1429
1430 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1431 #else
1432 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1433 #endif
1434 }
1435
1436 template <typename Helper>
1437 void testTimedLockUpgradeAbsolute(typename Helper::mutex& m, const long long jumpMs)
1438 {
1439 #ifndef SKIP_DATETIME_FUNCTIONS
1440 typename Helper::steady_time_point before(Helper::steadyNow());
1441 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1442 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1443 bool succeeded = m.timed_lock_upgrade(ptNow + ptDur);
1444 typename Helper::steady_time_point after(Helper::steadyNow());
1445
1446 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1447 #else
1448 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1449 #endif
1450 }
1451
1452 //--------------------------------------
1453
1454 template <typename Helper>
1455 void testTryUnlockSharedAndLockFor(typename Helper::mutex& m, const long long jumpMs)
1456 {
1457 boost::shared_lock_guard<typename Helper::mutex> g(m);
1458
1459 typename Helper::steady_time_point before(Helper::steadyNow());
1460 bool succeeded = m.try_unlock_shared_and_lock_for(Helper::waitDur);
1461 typename Helper::steady_time_point after(Helper::steadyNow());
1462
1463 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1464 }
1465
1466 template <typename Helper>
1467 void testTryUnlockSharedAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1468 {
1469 boost::shared_lock_guard<typename Helper::mutex> g(m);
1470
1471 typename Helper::steady_time_point before(Helper::steadyNow());
1472 bool succeeded = m.try_unlock_shared_and_lock_until(Helper::steadyNow() + Helper::waitDur);
1473 typename Helper::steady_time_point after(Helper::steadyNow());
1474
1475 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1476 }
1477
1478 template <typename Helper>
1479 void testTryUnlockSharedAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1480 {
1481 boost::shared_lock_guard<typename Helper::mutex> g(m);
1482
1483 typename Helper::steady_time_point before(Helper::steadyNow());
1484 bool succeeded = m.try_unlock_shared_and_lock_until(Helper::systemNow() + Helper::waitDur);
1485 typename Helper::steady_time_point after(Helper::steadyNow());
1486
1487 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1488 }
1489
1490 template <typename Helper>
1491 void testTryUnlockSharedAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1492 {
1493 boost::shared_lock_guard<typename Helper::mutex> g(m);
1494
1495 typename Helper::steady_time_point before(Helper::steadyNow());
1496 bool succeeded = m.try_unlock_shared_and_lock_until(Helper::customNow() + Helper::waitDur);
1497 typename Helper::steady_time_point after(Helper::steadyNow());
1498
1499 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1500 }
1501
1502 //--------------------------------------
1503
1504 template <typename Helper>
1505 void testTryUnlockUpgradeAndLockFor(typename Helper::mutex& m, const long long jumpMs)
1506 {
1507 boost::upgrade_lock<typename Helper::mutex> g(m);
1508
1509 typename Helper::steady_time_point before(Helper::steadyNow());
1510 bool succeeded = m.try_unlock_upgrade_and_lock_for(Helper::waitDur);
1511 typename Helper::steady_time_point after(Helper::steadyNow());
1512
1513 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1514 }
1515
1516 template <typename Helper>
1517 void testTryUnlockUpgradeAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1518 {
1519 boost::upgrade_lock<typename Helper::mutex> g(m);
1520
1521 typename Helper::steady_time_point before(Helper::steadyNow());
1522 bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::steadyNow() + Helper::waitDur);
1523 typename Helper::steady_time_point after(Helper::steadyNow());
1524
1525 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1526 }
1527
1528 template <typename Helper>
1529 void testTryUnlockUpgradeAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1530 {
1531 boost::upgrade_lock<typename Helper::mutex> g(m);
1532
1533 typename Helper::steady_time_point before(Helper::steadyNow());
1534 bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::systemNow() + Helper::waitDur);
1535 typename Helper::steady_time_point after(Helper::steadyNow());
1536
1537 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1538 }
1539
1540 template <typename Helper>
1541 void testTryUnlockUpgradeAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1542 {
1543 boost::upgrade_lock<typename Helper::mutex> g(m);
1544
1545 typename Helper::steady_time_point before(Helper::steadyNow());
1546 bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::customNow() + Helper::waitDur);
1547 typename Helper::steady_time_point after(Helper::steadyNow());
1548
1549 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1550 }
1551
1552 //--------------------------------------
1553
1554 template <typename Helper>
1555 void testTryUnlockSharedAndLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs)
1556 {
1557 boost::shared_lock_guard<typename Helper::mutex> g(m);
1558
1559 typename Helper::steady_time_point before(Helper::steadyNow());
1560 bool succeeded = m.try_unlock_shared_and_lock_upgrade_for(Helper::waitDur);
1561 typename Helper::steady_time_point after(Helper::steadyNow());
1562
1563 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1564 }
1565
1566 template <typename Helper>
1567 void testTryUnlockSharedAndLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs)
1568 {
1569 boost::shared_lock_guard<typename Helper::mutex> g(m);
1570
1571 typename Helper::steady_time_point before(Helper::steadyNow());
1572 bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur);
1573 typename Helper::steady_time_point after(Helper::steadyNow());
1574
1575 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good);
1576 }
1577
1578 template <typename Helper>
1579 void testTryUnlockSharedAndLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs)
1580 {
1581 boost::shared_lock_guard<typename Helper::mutex> g(m);
1582
1583 typename Helper::steady_time_point before(Helper::steadyNow());
1584 bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::systemNow() + Helper::waitDur);
1585 typename Helper::steady_time_point after(Helper::steadyNow());
1586
1587 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1588 }
1589
1590 template <typename Helper>
1591 void testTryUnlockSharedAndLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs)
1592 {
1593 boost::shared_lock_guard<typename Helper::mutex> g(m);
1594
1595 typename Helper::steady_time_point before(Helper::steadyNow());
1596 bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::customNow() + Helper::waitDur);
1597 typename Helper::steady_time_point after(Helper::steadyNow());
1598
1599 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good);
1600 }
1601
1602 #endif
1603
1604 //--------------------------------------
1605
1606 // Only Boost supports upgrade mutexes
1607
1608 template <typename Helper>
1609 void testMutexUpgradeBoost(const std::string& name)
1610 {
1611 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
1612 std::cout << std::endl;
1613 runTestWithUnique<Helper>(testTryLockUpgradeFor <Helper>, name + "::try_lock_upgrade_for()");
1614 runTestWithUnique<Helper>(testTryLockUpgradeUntilSteady<Helper>, name + "::try_lock_upgrade_until(), steady time");
1615 runTestWithUnique<Helper>(testTryLockUpgradeUntilSystem<Helper>, name + "::try_lock_upgrade_until(), system time");
1616 runTestWithUnique<Helper>(testTryLockUpgradeUntilCustom<Helper>, name + "::try_lock_upgrade_until(), custom time");
1617 runTestWithUnique<Helper>(testTimedLockUpgradeRelative <Helper>, name + "::timed_lock_upgrade(), relative time");
1618 runTestWithUnique<Helper>(testTimedLockUpgradeAbsolute <Helper>, name + "::timed_lock_upgrade(), absolute time");
1619
1620 std::cout << std::endl;
1621 runTestWithShared<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_for()");
1622 runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_until(), steady time");
1623 runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_until(), system time");
1624 runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_until(), custom time");
1625
1626 std::cout << std::endl;
1627 runTestWithShared<Helper>(testTryUnlockUpgradeAndLockFor <Helper>, name + "::try_unlock_upgrade_and_lock_for()");
1628 runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSteady<Helper>, name + "::try_unlock_upgrade_and_lock_until(), steady time");
1629 runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSystem<Helper>, name + "::try_unlock_upgrade_and_lock_until(), system time");
1630 runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilCustom<Helper>, name + "::try_unlock_upgrade_and_lock_until(), custom time");
1631
1632 std::cout << std::endl;
1633 runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_upgrade_for()");
1634 runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), steady time");
1635 runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), system time");
1636 runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), custom time");
1637 #endif
1638 }
1639
1640 /******************************************************************************/
1641
1642 // Test Future Wait
1643
1644 template <typename Helper>
1645 void testFutureWaitFor(const long long jumpMs)
1646 {
1647 typename Helper::packaged_task pt(returnFalse);
1648 typename Helper::future f = pt.get_future();
1649
1650 typename Helper::steady_time_point before(Helper::steadyNow());
1651 bool timeout = (f.wait_for(Helper::waitDur) == Helper::future_status::timeout);
1652 typename Helper::steady_time_point after(Helper::steadyNow());
1653
1654 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1655 }
1656
1657 template <typename Helper>
1658 void testFutureWaitUntilSteady(const long long jumpMs)
1659 {
1660 typename Helper::packaged_task pt(returnFalse);
1661 typename Helper::future f = pt.get_future();
1662
1663 typename Helper::steady_time_point before(Helper::steadyNow());
1664 bool timeout = (f.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout);
1665 typename Helper::steady_time_point after(Helper::steadyNow());
1666
1667 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1668 }
1669
1670 template <typename Helper>
1671 void testFutureWaitUntilSystem(const long long jumpMs)
1672 {
1673 typename Helper::packaged_task pt(returnFalse);
1674 typename Helper::future f = pt.get_future();
1675
1676 typename Helper::steady_time_point before(Helper::steadyNow());
1677 bool timeout = (f.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout);
1678 typename Helper::steady_time_point after(Helper::steadyNow());
1679
1680 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1681 }
1682
1683 template <typename Helper>
1684 void testFutureWaitUntilCustom(const long long jumpMs)
1685 {
1686 typename Helper::packaged_task pt(returnFalse);
1687 typename Helper::future f = pt.get_future();
1688
1689 typename Helper::steady_time_point before(Helper::steadyNow());
1690 bool timeout = (f.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout);
1691 typename Helper::steady_time_point after(Helper::steadyNow());
1692
1693 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1694 }
1695
1696 //--------------------------------------
1697
1698 template <typename Helper>
1699 void testFutureTimedWaitRelative(const long long jumpMs)
1700 {
1701 #ifndef SKIP_DATETIME_FUNCTIONS
1702 typename Helper::packaged_task pt(returnFalse);
1703 typename Helper::future f = pt.get_future();
1704
1705 typename Helper::steady_time_point before(Helper::steadyNow());
1706 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1707 bool noTimeout = f.timed_wait(ptDur);
1708 typename Helper::steady_time_point after(Helper::steadyNow());
1709
1710 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1711 #else
1712 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1713 #endif
1714 }
1715
1716 template <typename Helper>
1717 void testFutureTimedWaitAbsolute(const long long jumpMs)
1718 {
1719 #ifndef SKIP_DATETIME_FUNCTIONS
1720 typename Helper::packaged_task pt(returnFalse);
1721 typename Helper::future f = pt.get_future();
1722
1723 typename Helper::steady_time_point before(Helper::steadyNow());
1724 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1725 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1726 bool noTimeout = f.timed_wait_until(ptNow + ptDur);
1727 typename Helper::steady_time_point after(Helper::steadyNow());
1728
1729 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1730 #else
1731 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1732 #endif
1733 }
1734
1735 //--------------------------------------
1736
1737 template <typename Helper>
1738 void testFutureStd(const std::string& name)
1739 {
1740 std::cout << std::endl;
1741 runTestWithNone<Helper>(testFutureWaitFor <Helper>, name + "::wait_for()");
1742 runTestWithNone<Helper>(testFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
1743 runTestWithNone<Helper>(testFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time");
1744 runTestWithNone<Helper>(testFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
1745 }
1746
1747 template <typename Helper>
1748 void testFutureBoost(const std::string& name)
1749 {
1750 testFutureStd<Helper>(name);
1751
1752 // Boost-only functions
1753 runTestWithNone<Helper>(testFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
1754 runTestWithNone<Helper>(testFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time");
1755 }
1756
1757 /******************************************************************************/
1758
1759 // Test Shared Future Wait
1760
1761 template <typename Helper>
1762 void testSharedFutureWaitFor(const long long jumpMs)
1763 {
1764 typename Helper::packaged_task pt(returnFalse);
1765 typename Helper::future f = pt.get_future();
1766 typename Helper::shared_future sf = boost::move(f);
1767
1768 typename Helper::steady_time_point before(Helper::steadyNow());
1769 bool timeout = (sf.wait_for(Helper::waitDur) == Helper::future_status::timeout);
1770 typename Helper::steady_time_point after(Helper::steadyNow());
1771
1772 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1773 }
1774
1775 template <typename Helper>
1776 void testSharedFutureWaitUntilSteady(const long long jumpMs)
1777 {
1778 typename Helper::packaged_task pt(returnFalse);
1779 typename Helper::future f = pt.get_future();
1780 typename Helper::shared_future sf = boost::move(f);
1781
1782 typename Helper::steady_time_point before(Helper::steadyNow());
1783 bool timeout = (sf.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout);
1784 typename Helper::steady_time_point after(Helper::steadyNow());
1785
1786 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1787 }
1788
1789 template <typename Helper>
1790 void testSharedFutureWaitUntilSystem(const long long jumpMs)
1791 {
1792 typename Helper::packaged_task pt(returnFalse);
1793 typename Helper::future f = pt.get_future();
1794 typename Helper::shared_future sf = boost::move(f);
1795
1796 typename Helper::steady_time_point before(Helper::steadyNow());
1797 bool timeout = (sf.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout);
1798 typename Helper::steady_time_point after(Helper::steadyNow());
1799
1800 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1801 }
1802
1803 template <typename Helper>
1804 void testSharedFutureWaitUntilCustom(const long long jumpMs)
1805 {
1806 typename Helper::packaged_task pt(returnFalse);
1807 typename Helper::future f = pt.get_future();
1808 typename Helper::shared_future sf = boost::move(f);
1809
1810 typename Helper::steady_time_point before(Helper::steadyNow());
1811 bool timeout = (sf.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout);
1812 typename Helper::steady_time_point after(Helper::steadyNow());
1813
1814 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1815 }
1816
1817 //--------------------------------------
1818
1819 template <typename Helper>
1820 void testSharedFutureTimedWaitRelative(const long long jumpMs)
1821 {
1822 #ifndef SKIP_DATETIME_FUNCTIONS
1823 typename Helper::packaged_task pt(returnFalse);
1824 typename Helper::future f = pt.get_future();
1825 typename Helper::shared_future sf = boost::move(f);
1826
1827 typename Helper::steady_time_point before(Helper::steadyNow());
1828 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1829 bool noTimeout = sf.timed_wait(ptDur);
1830 typename Helper::steady_time_point after(Helper::steadyNow());
1831
1832 checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout);
1833 #else
1834 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1835 #endif
1836 }
1837
1838 template <typename Helper>
1839 void testSharedFutureTimedWaitAbsolute(const long long jumpMs)
1840 {
1841 #ifndef SKIP_DATETIME_FUNCTIONS
1842 typename Helper::packaged_task pt(returnFalse);
1843 typename Helper::future f = pt.get_future();
1844 typename Helper::shared_future sf = boost::move(f);
1845
1846 typename Helper::steady_time_point before(Helper::steadyNow());
1847 boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time());
1848 boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count());
1849 bool noTimeout = sf.timed_wait_until(ptNow + ptDur);
1850 typename Helper::steady_time_point after(Helper::steadyNow());
1851
1852 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout);
1853 #else
1854 checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na);
1855 #endif
1856 }
1857
1858 //--------------------------------------
1859
1860 template <typename Helper>
1861 void testSharedFutureStd(const std::string& name)
1862 {
1863 std::cout << std::endl;
1864 runTestWithNone<Helper>(testSharedFutureWaitFor <Helper>, name + "::wait_for()");
1865 runTestWithNone<Helper>(testSharedFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time");
1866 runTestWithNone<Helper>(testSharedFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time");
1867 runTestWithNone<Helper>(testSharedFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time");
1868 }
1869
1870 template <typename Helper>
1871 void testSharedFutureBoost(const std::string& name)
1872 {
1873 testSharedFutureStd<Helper>(name);
1874
1875 // Boost-only functions
1876 runTestWithNone<Helper>(testSharedFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time");
1877 runTestWithNone<Helper>(testSharedFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time");
1878 }
1879
1880 /******************************************************************************/
1881
1882 // Test Sync Priority Queue
1883
1884 template <typename Helper>
1885 void testSyncPriorityQueuePullFor(const long long jumpMs)
1886 {
1887 boost::sync_priority_queue<int> q;
1888 int i;
1889
1890 typename Helper::steady_time_point before(Helper::steadyNow());
1891 bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
1892 typename Helper::steady_time_point after(Helper::steadyNow());
1893
1894 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1895 }
1896
1897 template <typename Helper>
1898 void testSyncPriorityQueuePullUntilSteady(const long long jumpMs)
1899 {
1900 boost::sync_priority_queue<int> q;
1901 int i;
1902
1903 typename Helper::steady_time_point before(Helper::steadyNow());
1904 bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
1905 typename Helper::steady_time_point after(Helper::steadyNow());
1906
1907 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1908 }
1909
1910 template <typename Helper>
1911 void testSyncPriorityQueuePullUntilSystem(const long long jumpMs)
1912 {
1913 boost::sync_priority_queue<int> q;
1914 int i;
1915
1916 typename Helper::steady_time_point before(Helper::steadyNow());
1917 bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
1918 typename Helper::steady_time_point after(Helper::steadyNow());
1919
1920 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1921 }
1922
1923 template <typename Helper>
1924 void testSyncPriorityQueuePullUntilCustom(const long long jumpMs)
1925 {
1926 boost::sync_priority_queue<int> q;
1927 int i;
1928
1929 typename Helper::steady_time_point before(Helper::steadyNow());
1930 bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
1931 typename Helper::steady_time_point after(Helper::steadyNow());
1932
1933 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
1934 }
1935
1936 //--------------------------------------
1937
1938 // Only Boost supports sync_priority_queue
1939
1940 template <typename Helper>
1941 void testSyncPriorityQueueBoost(const std::string& name)
1942 {
1943 std::cout << std::endl;
1944 runTestWithNone<Helper>(testSyncPriorityQueuePullFor <Helper>, name + "::pull_for()");
1945 runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSteady<Helper>, name + "::pull_until(), steady time");
1946 runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSystem<Helper>, name + "::pull_until(), system time");
1947 runTestWithNone<Helper>(testSyncPriorityQueuePullUntilCustom<Helper>, name + "::pull_until(), custom time");
1948 }
1949
1950 /******************************************************************************/
1951
1952 // Test Sync Timed Queue
1953
1954 template <typename Helper>
1955 void testSyncTimedQueuePullForEmptySteady(const long long jumpMs)
1956 {
1957 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
1958 int i;
1959
1960 typename Helper::steady_time_point before(Helper::steadyNow());
1961 bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
1962 typename Helper::steady_time_point after(Helper::steadyNow());
1963
1964 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1965 }
1966
1967 template <typename Helper>
1968 void testSyncTimedQueuePullForEmptySystem(const long long jumpMs)
1969 {
1970 boost::sync_timed_queue<int, typename Helper::system_clock> q;
1971 int i;
1972
1973 typename Helper::steady_time_point before(Helper::steadyNow());
1974 bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
1975 typename Helper::steady_time_point after(Helper::steadyNow());
1976
1977 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1978 }
1979
1980 template <typename Helper>
1981 void testSyncTimedQueuePullForEmptyCustom(const long long jumpMs)
1982 {
1983 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
1984 int i;
1985
1986 typename Helper::steady_time_point before(Helper::steadyNow());
1987 bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout);
1988 typename Helper::steady_time_point after(Helper::steadyNow());
1989
1990 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
1991 }
1992
1993 template <typename Helper>
1994 void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs)
1995 {
1996 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
1997 int i;
1998
1999 typename Helper::steady_time_point before(Helper::steadyNow());
2000 bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
2001 typename Helper::steady_time_point after(Helper::steadyNow());
2002
2003 checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout);
2004 }
2005
2006 template <typename Helper>
2007 void testSyncTimedQueuePullUntilEmptySystem(const long long jumpMs)
2008 {
2009 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2010 int i;
2011
2012 typename Helper::steady_time_point before(Helper::steadyNow());
2013 bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
2014 typename Helper::steady_time_point after(Helper::steadyNow());
2015
2016 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
2017 }
2018
2019 template <typename Helper>
2020 void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs)
2021 {
2022 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2023 int i;
2024
2025 typename Helper::steady_time_point before(Helper::steadyNow());
2026 bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout);
2027 typename Helper::steady_time_point after(Helper::steadyNow());
2028
2029 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout);
2030 }
2031
2032 //--------------------------------------
2033
2034 template <typename Helper>
2035 void testSyncTimedQueuePullForNotReadySteady(const long long jumpMs)
2036 {
2037 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
2038 q.push(0, typename Helper::milliseconds(10000)); // a long time
2039 int i;
2040
2041 typename Helper::steady_time_point before(Helper::steadyNow());
2042 bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
2043 typename Helper::steady_time_point after(Helper::steadyNow());
2044
2045 checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
2046 }
2047
2048 template <typename Helper>
2049 void testSyncTimedQueuePullForNotReadySystem(const long long jumpMs)
2050 {
2051 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2052 q.push(0, typename Helper::milliseconds(10000)); // a long time
2053 int i;
2054
2055 typename Helper::steady_time_point before(Helper::steadyNow());
2056 bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
2057 typename Helper::steady_time_point after(Helper::steadyNow());
2058
2059 checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
2060 }
2061
2062 template <typename Helper>
2063 void testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs)
2064 {
2065 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2066 q.push(0, typename Helper::milliseconds(10000)); // a long time
2067 int i;
2068
2069 typename Helper::steady_time_point before(Helper::steadyNow());
2070 bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready);
2071 typename Helper::steady_time_point after(Helper::steadyNow());
2072
2073 checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
2074 }
2075
2076 template <typename Helper>
2077 void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs)
2078 {
2079 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
2080 q.push(0, typename Helper::milliseconds(10000)); // a long time
2081 int i;
2082
2083 typename Helper::steady_time_point before(Helper::steadyNow());
2084 bool notReady = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
2085 typename Helper::steady_time_point after(Helper::steadyNow());
2086
2087 checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad);
2088 }
2089
2090 template <typename Helper>
2091 void testSyncTimedQueuePullUntilNotReadySystem(const long long jumpMs)
2092 {
2093 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2094 q.push(0, typename Helper::milliseconds(10000)); // a long time
2095 int i;
2096
2097 typename Helper::steady_time_point before(Helper::steadyNow());
2098 bool notReady = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
2099 typename Helper::steady_time_point after(Helper::steadyNow());
2100
2101 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad);
2102 }
2103
2104 template <typename Helper>
2105 void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs)
2106 {
2107 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2108 q.push(0, typename Helper::milliseconds(10000)); // a long time
2109 int i;
2110
2111 typename Helper::steady_time_point before(Helper::steadyNow());
2112 bool notReady = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready);
2113 typename Helper::steady_time_point after(Helper::steadyNow());
2114
2115 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad);
2116 }
2117
2118 //--------------------------------------
2119
2120 template <typename Helper>
2121 void testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs)
2122 {
2123 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
2124 q.push(0, Helper::waitDur);
2125 int i;
2126
2127 typename Helper::steady_time_point before(Helper::steadyNow());
2128 bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2129 typename Helper::steady_time_point after(Helper::steadyNow());
2130
2131 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
2132 }
2133
2134 template <typename Helper>
2135 void testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs)
2136 {
2137 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2138 q.push(0, Helper::waitDur);
2139 int i;
2140
2141 typename Helper::steady_time_point before(Helper::steadyNow());
2142 bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2143 typename Helper::steady_time_point after(Helper::steadyNow());
2144
2145 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2146 }
2147
2148 template <typename Helper>
2149 void testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs)
2150 {
2151 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2152 q.push(0, Helper::waitDur);
2153 int i;
2154
2155 typename Helper::steady_time_point before(Helper::steadyNow());
2156 bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2157 typename Helper::steady_time_point after(Helper::steadyNow());
2158
2159 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2160 }
2161
2162 template <typename Helper>
2163 void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs)
2164 {
2165 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
2166 q.push(0, Helper::steadyNow() + Helper::waitDur);
2167 int i;
2168
2169 typename Helper::steady_time_point before(Helper::steadyNow());
2170 bool succeeded = (q.pull_until(Helper::steadyNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2171 typename Helper::steady_time_point after(Helper::steadyNow());
2172
2173 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
2174 }
2175
2176 template <typename Helper>
2177 void testSyncTimedQueuePullUntilSucceedsSystem(const long long jumpMs)
2178 {
2179 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2180 q.push(0, Helper::systemNow() + Helper::waitDur);
2181 int i;
2182
2183 typename Helper::steady_time_point before(Helper::steadyNow());
2184 bool succeeded = (q.pull_until(Helper::systemNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2185 typename Helper::steady_time_point after(Helper::steadyNow());
2186
2187 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2188 }
2189
2190 template <typename Helper>
2191 void testSyncTimedQueuePullUntilSucceedsCustom(const long long jumpMs)
2192 {
2193 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2194 q.push(0, Helper::customNow() + Helper::waitDur);
2195 int i;
2196
2197 typename Helper::steady_time_point before(Helper::steadyNow());
2198 bool succeeded = (q.pull_until(Helper::customNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success);
2199 typename Helper::steady_time_point after(Helper::steadyNow());
2200
2201 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2202 }
2203
2204 //--------------------------------------
2205
2206 template <typename Helper>
2207 void testSyncTimedQueueWaitPullSucceedsSteady(const long long jumpMs)
2208 {
2209 boost::sync_timed_queue<int, typename Helper::steady_clock> q;
2210 q.push(0, Helper::steadyNow() + Helper::waitDur);
2211 int i;
2212
2213 typename Helper::steady_time_point before(Helper::steadyNow());
2214 bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
2215 typename Helper::steady_time_point after(Helper::steadyNow());
2216
2217 checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad);
2218 }
2219
2220 template <typename Helper>
2221 void testSyncTimedQueueWaitPullSucceedsSystem(const long long jumpMs)
2222 {
2223 boost::sync_timed_queue<int, typename Helper::system_clock> q;
2224 q.push(0, Helper::systemNow() + Helper::waitDur);
2225 int i;
2226
2227 typename Helper::steady_time_point before(Helper::steadyNow());
2228 bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
2229 typename Helper::steady_time_point after(Helper::steadyNow());
2230
2231 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2232 }
2233
2234 template <typename Helper>
2235 void testSyncTimedQueueWaitPullSucceedsCustom(const long long jumpMs)
2236 {
2237 boost::sync_timed_queue<int, typename Helper::custom_clock> q;
2238 q.push(0, Helper::customNow() + Helper::waitDur);
2239 int i;
2240
2241 typename Helper::steady_time_point before(Helper::steadyNow());
2242 bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success);
2243 typename Helper::steady_time_point after(Helper::steadyNow());
2244
2245 checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad);
2246 }
2247
2248 //--------------------------------------
2249
2250 // Only Boost supports sync_timed_queue
2251
2252 template <typename Helper>
2253 void testSyncTimedQueueBoost(const std::string& name)
2254 {
2255 std::cout << std::endl;
2256 runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySteady <Helper>, name + "::pull_for(), empty, steady time");
2257 runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySystem <Helper>, name + "::pull_for(), empty, system time");
2258 runTestWithNone<Helper>(testSyncTimedQueuePullForEmptyCustom <Helper>, name + "::pull_for(), empty, custom time");
2259 runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySteady<Helper>, name + "::pull_until(), empty, steady time");
2260 runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time");
2261 runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time");
2262
2263 std::cout << std::endl;
2264 runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySteady <Helper>, name + "::pull_for(), not ready, steady time");
2265 runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySystem <Helper>, name + "::pull_for(), not ready, system time");
2266 runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadyCustom <Helper>, name + "::pull_for(), not ready, custom time");
2267 runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySteady<Helper>, name + "::pull_until(), not ready, steady time");
2268 runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time");
2269 runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time");
2270
2271 std::cout << std::endl;
2272 runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSteady <Helper>, name + "::pull_for(), succeeds, steady time");
2273 runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSystem <Helper>, name + "::pull_for(), succeeds, system time");
2274 runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsCustom <Helper>, name + "::pull_for(), succeeds, custom time");
2275 runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSteady<Helper>, name + "::pull_until(), succeeds, steady time");
2276 runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time");
2277 runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time");
2278
2279 std::cout << std::endl;
2280 runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSteady<Helper>, name + "::wait_pull(), succeeds, steady time");
2281 runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSystem<Helper>, name + "::wait_pull(), succeeds, system time");
2282 runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsCustom<Helper>, name + "::wait_pull(), succeeds, custom time");
2283 }
2284
2285 /******************************************************************************/
2286
2287 int main()
2288 {
2289 std::cout << std::endl;
2290 std::cout << "INFO: This test requires root/Administrator privileges in order to change the system clock." << std::endl;
2291 std::cout << "INFO: Disable NTP while running this test to prevent NTP from changing the system clock." << std::endl;
2292 std::cout << std::endl;
2293
2294 std::cout << "BOOST_HAS_PTHREAD_DELAY_NP: ";
2295 #ifdef BOOST_HAS_PTHREAD_DELAY_NP
2296 std::cout << "YES" << std::endl;
2297 #else
2298 std::cout << "NO" << std::endl;
2299 #endif
2300
2301 std::cout << "BOOST_HAS_NANOSLEEP: ";
2302 #ifdef BOOST_HAS_NANOSLEEP
2303 std::cout << "YES" << std::endl;
2304 #else
2305 std::cout << "NO" << std::endl;
2306 #endif
2307
2308 std::cout << "BOOST_THREAD_SLEEP_FOR_IS_STEADY: ";
2309 #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
2310 std::cout << "YES" << std::endl;
2311 #else
2312 std::cout << "NO" << std::endl;
2313 #endif
2314
2315 std::cout << "CLOCK_MONOTONIC: ";
2316 #ifdef CLOCK_MONOTONIC
2317 std::cout << "YES" << std::endl;
2318 #else
2319 std::cout << "NO" << std::endl;
2320 #endif
2321
2322 std::cout << "BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN: ";
2323 #ifdef BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN
2324 std::cout << "YES" << std::endl;
2325 #else
2326 std::cout << "NO" << std::endl;
2327 #endif
2328
2329 std::cout << "BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS: ";
2330 #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS
2331 std::cout << "YES" << std::endl;
2332 #else
2333 std::cout << "NO" << std::endl;
2334 #endif
2335
2336 std::cout << "BOOST_THREAD_V2_SHARED_MUTEX: ";
2337 #ifdef BOOST_THREAD_V2_SHARED_MUTEX
2338 std::cout << "YES" << std::endl;
2339 #else
2340 std::cout << "NO" << std::endl;
2341 #endif
2342
2343 std::cout << "BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC: ";
2344 #ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC
2345 std::cout << "YES" << std::endl;
2346 #else
2347 std::cout << "NO" << std::endl;
2348 #endif
2349
2350 std::cout << std::endl;
2351 std::cout << "Wait Time: " << s_waitMs << " ms" << std::endl;
2352 std::cout << "Short Jump Time: " << s_shortJumpMs << " ms" << std::endl;
2353 std::cout << "Long Jump Time: " << s_longJumpMs << " ms" << std::endl;
2354 std::cout << "Sleep Before Jump Time: " << s_sleepBeforeJumpMs << " ms" << std::endl;
2355 std::cout << "Max Early Error: " << s_maxEarlyErrorMs << " ms" << std::endl;
2356 std::cout << "Max Late Error: " << s_maxLateErrorMs << " ms" << std::endl;
2357
2358 testSleepBoost <BoostHelper< > >("boost");
2359 testSleepNoIntBoost <BoostHelper< > >("boost");
2360 testSleepNoThreadBoost <BoostHelper< > >("boost");
2361 testSleepNoThreadNoIntBoost<BoostHelper< > >("boost");
2362 testJoinBoost <BoostHelper< > >("boost");
2363 testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable");
2364 testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable");
2365 testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any");
2366 testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any");
2367 testMutexBoost <BoostHelper<boost::timed_mutex > >("boost::timed_mutex");
2368 testMutexBoost <BoostHelper<boost::recursive_timed_mutex > >("boost::recursive_timed_mutex");
2369 testMutexBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
2370 testMutexSharedBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
2371 testMutexUpgradeBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex
2372 testFutureBoost <BoostHelper< > >("boost::future");
2373 testSharedFutureBoost <BoostHelper< > >("boost::shared_future");
2374 testSyncPriorityQueueBoost <BoostHelper< > >("boost::sync_priority_queue");
2375 testSyncTimedQueueBoost <BoostHelper< > >("boost::sync_timed_queue");
2376
2377 #ifdef TEST_CPP14_FEATURES
2378 testSleepStd <StdHelper< > >("std");
2379 testSleepNoThreadStd<StdHelper< > >("std");
2380 testCondVarStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable");
2381 testCondVarPredStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable");
2382 testCondVarStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any");
2383 testCondVarPredStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any");
2384 testMutexStd <StdHelper<std::timed_mutex > >("std::timed_mutex");
2385 testMutexStd <StdHelper<std::recursive_timed_mutex > >("std::recursive_timed_mutex");
2386 testMutexStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex");
2387 testMutexSharedStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex");
2388 testFutureStd <StdHelper< > >("std::future");
2389 testSharedFutureStd <StdHelper< > >("std::shared_future");
2390 #endif
2391
2392 std::cout << std::endl;
2393 std::cout << "Number of Tests Run: " << g_numTestsRun << std::endl;
2394 std::cout << "Number of Tests Passed: " << g_numTestsPassed << std::endl;
2395 std::cout << "Number of Tests Failed: " << g_numTestsFailed << std::endl;
2396
2397 return 0;
2398 }