1 #ifdef _WIN32
2 	#include <windows.h>
3 #else
4 	#include <sys/time.h>
5 #endif
6 
7 #include "boost/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 
now()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 
now()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>
sleep_forBoostHelper150     static void sleep_for(T d)
151     {
152         boost::this_thread::sleep_for(d);
153     }
154 
155     template <typename T>
sleep_for_no_intBoostHelper156     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>
sleep_untilBoostHelper162     static void sleep_until(T t)
163     {
164         boost::this_thread::sleep_until(t);
165     }
166 
167     template <typename T>
sleep_until_no_intBoostHelper168     static void sleep_until_no_int(T t)
169     {
170         boost::this_thread::no_interruption_point::sleep_until(t);
171     }
172 
systemNowBoostHelper173     static system_time_point systemNow()
174     {
175         return system_clock::now();
176     }
177 
steadyNowBoostHelper178     static steady_time_point steadyNow()
179     {
180         return steady_clock::now();
181     }
182 
customNowBoostHelper183     static custom_time_point customNow()
184     {
185         return custom_clock::now();
186     }
187 
188     template <class ToDuration, class Rep, class Period>
duration_castBoostHelper189     static ToDuration duration_cast(const boost::chrono::duration<Rep, Period>& d)
190     {
191         return boost::chrono::duration_cast<ToDuration>(d);
192     }
193 
zeroBoostHelper194     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>
sleep_forStdHelper237     static void sleep_for(T d)
238     {
239         std::this_thread::sleep_for(d);
240     }
241 
242     template <typename T>
sleep_untilStdHelper243     static void sleep_until(T t)
244     {
245         std::this_thread::sleep_until(t);
246     }
247 
systemNowStdHelper248     static system_time_point systemNow()
249     {
250         return system_clock::now();
251     }
252 
steadyNowStdHelper253     static steady_time_point steadyNow()
254     {
255         return steady_clock::now();
256     }
257 
customNowStdHelper258     static custom_time_point customNow()
259     {
260         return custom_clock::now();
261     }
262 
263     template <class ToDuration, class Rep, class Period>
duration_castStdHelper264     static ToDuration duration_cast(const std::chrono::duration<Rep, Period>& d)
265     {
266         return std::chrono::duration_cast<ToDuration>(d);
267     }
268 
zeroStdHelper269     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 
changeSystemTime(long long changeMs)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 
changeSystemTime(long long changeMs)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>
checkWaitTime(typename Helper::nanoseconds expected,typename Helper::nanoseconds actual,RcEnum rc)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 
sleepForLongTime()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 
returnFalse()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>
runTestInContext(Context context,Function func,const std::string name)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>
noThreadContext(Function func,const long long jumpMs)520 void noThreadContext(Function func, const long long jumpMs)
521 {
522     func(jumpMs);
523 }
524 
525 template <typename Helper, typename Function>
threadContextWithNone(Function func,const long long jumpMs)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>
threadContextWithUnique(Function func,const long long jumpMs)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>
threadContextWithShared(Function func,const long long jumpMs)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>
threadContextWithUpgrade(Function func,const long long jumpMs)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>
runTest(Function func,const std::string name)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>
runTestWithNone(Function func,const std::string name)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>
runTestWithUnique(Function func,const std::string name)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>
runTestWithShared(Function func,const std::string name)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>
runTestWithUpgrade(Function func,const std::string name)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>
testSleepFor(const long long jumpMs)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>
testSleepUntilSteady(const long long jumpMs)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>
testSleepUntilSystem(const long long jumpMs)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>
testSleepUntilCustom(const long long jumpMs)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>
testSleepRelative(const long long jumpMs)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>
testSleepAbsolute(const long long jumpMs)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>
testSleepStd(const std::string & name)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>
testSleepBoost(const std::string & name)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>
testSleepNoThreadStd(const std::string & name)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>
testSleepNoThreadBoost(const std::string & name)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>
testSleepForNoInt(const long long jumpMs)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>
testSleepUntilNoIntSteady(const long long jumpMs)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>
testSleepUntilNoIntSystem(const long long jumpMs)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>
testSleepUntilNoIntCustom(const long long jumpMs)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>
testSleepNoIntRelative(const long long jumpMs)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>
testSleepNoIntAbsolute(const long long jumpMs)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>
testSleepNoIntBoost(const std::string & name)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>
testSleepNoThreadNoIntBoost(const std::string & name)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>
testTryJoinFor(const long long jumpMs)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>
testTryJoinUntilSteady(const long long jumpMs)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>
testTryJoinUntilSystem(const long long jumpMs)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>
testTryJoinUntilCustom(const long long jumpMs)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>
testTimedJoinRelative(const long long jumpMs)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>
testTimedJoinAbsolute(const long long jumpMs)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>
testJoinBoost(const std::string & name)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>
testCondVarWaitFor(const long long jumpMs)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>
testCondVarWaitUntilSteady(const long long jumpMs)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>
testCondVarWaitUntilSystem(const long long jumpMs)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>
testCondVarWaitUntilCustom(const long long jumpMs)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>
testCondVarTimedWaitRelative(const long long jumpMs)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>
testCondVarTimedWaitAbsolute(const long long jumpMs)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>
testCondVarStd(const std::string & name)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>
testCondVarBoost(const std::string & name)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>
testCondVarWaitForPred(const long long jumpMs)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>
testCondVarWaitUntilPredSteady(const long long jumpMs)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>
testCondVarWaitUntilPredSystem(const long long jumpMs)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>
testCondVarWaitUntilPredCustom(const long long jumpMs)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>
testCondVarTimedWaitPredRelative(const long long jumpMs)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>
testCondVarTimedWaitPredAbsolute(const long long jumpMs)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>
testCondVarPredStd(const std::string & name)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>
testCondVarPredBoost(const std::string & name)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>
testTryLockFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockRelative(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockAbsolute(typename Helper::mutex & m,const long long jumpMs)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>
testMutexStd(const std::string & name)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>
testMutexBoost(const std::string & name)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>
testTryLockSharedFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockSharedUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockSharedUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockSharedUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockSharedRelative(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockSharedAbsolute(typename Helper::mutex & m,const long long jumpMs)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>
testMutexSharedStd(const std::string & name)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>
testMutexSharedBoost(const std::string & name)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>
testTryLockUpgradeFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUpgradeUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUpgradeUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryLockUpgradeUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockUpgradeRelative(typename Helper::mutex & m,const long long jumpMs)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>
testTimedLockUpgradeAbsolute(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockUpgradeAndLockFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockUpgradeAndLockUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockUpgradeAndLockUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockUpgradeAndLockUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUpgradeFor(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUpgradeUntilSteady(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUpgradeUntilSystem(typename Helper::mutex & m,const long long jumpMs)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>
testTryUnlockSharedAndLockUpgradeUntilCustom(typename Helper::mutex & m,const long long jumpMs)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>
testMutexUpgradeBoost(const std::string & name)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>
testFutureWaitFor(const long long jumpMs)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>
testFutureWaitUntilSteady(const long long jumpMs)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>
testFutureWaitUntilSystem(const long long jumpMs)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>
testFutureWaitUntilCustom(const long long jumpMs)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>
testFutureTimedWaitRelative(const long long jumpMs)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>
testFutureTimedWaitAbsolute(const long long jumpMs)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>
testFutureStd(const std::string & name)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>
testFutureBoost(const std::string & name)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>
testSharedFutureWaitFor(const long long jumpMs)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>
testSharedFutureWaitUntilSteady(const long long jumpMs)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>
testSharedFutureWaitUntilSystem(const long long jumpMs)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>
testSharedFutureWaitUntilCustom(const long long jumpMs)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>
testSharedFutureTimedWaitRelative(const long long jumpMs)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>
testSharedFutureTimedWaitAbsolute(const long long jumpMs)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>
testSharedFutureStd(const std::string & name)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>
testSharedFutureBoost(const std::string & name)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>
testSyncPriorityQueuePullFor(const long long jumpMs)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>
testSyncPriorityQueuePullUntilSteady(const long long jumpMs)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>
testSyncPriorityQueuePullUntilSystem(const long long jumpMs)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>
testSyncPriorityQueuePullUntilCustom(const long long jumpMs)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>
testSyncPriorityQueueBoost(const std::string & name)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>
testSyncTimedQueuePullForEmptySteady(const long long jumpMs)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>
testSyncTimedQueuePullForEmptySystem(const long long jumpMs)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>
testSyncTimedQueuePullForEmptyCustom(const long long jumpMs)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>
testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs)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>
testSyncTimedQueuePullUntilEmptySystem(const long long jumpMs)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>
testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs)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>
testSyncTimedQueuePullForNotReadySteady(const long long jumpMs)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>
testSyncTimedQueuePullForNotReadySystem(const long long jumpMs)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>
testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs)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>
testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs)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>
testSyncTimedQueuePullUntilNotReadySystem(const long long jumpMs)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>
testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs)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>
testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs)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>
testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs)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>
testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs)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>
testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs)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>
testSyncTimedQueuePullUntilSucceedsSystem(const long long jumpMs)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>
testSyncTimedQueuePullUntilSucceedsCustom(const long long jumpMs)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>
testSyncTimedQueueWaitPullSucceedsSteady(const long long jumpMs)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>
testSyncTimedQueueWaitPullSucceedsSystem(const long long jumpMs)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>
testSyncTimedQueueWaitPullSucceedsCustom(const long long jumpMs)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>
testSyncTimedQueueBoost(const std::string & name)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 
main()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 }
2399