| #ifdef _WIN32 |
| #include <windows.h> |
| #else |
| #include <sys/time.h> |
| #endif |
| |
| #include "boost/bind/bind.hpp" |
| #include "boost/chrono.hpp" |
| #include "boost/chrono/ceil.hpp" |
| #include "boost/date_time.hpp" |
| #include "boost/thread/concurrent_queues/sync_priority_queue.hpp" |
| #include "boost/thread/concurrent_queues/sync_timed_queue.hpp" |
| #include "boost/thread/future.hpp" |
| #include "boost/thread/mutex.hpp" |
| #include "boost/thread/recursive_mutex.hpp" |
| #include "boost/thread/shared_lock_guard.hpp" |
| #include "boost/thread/shared_mutex.hpp" |
| #include "boost/thread/thread.hpp" |
| |
| #include <iomanip> |
| #ifdef TEST_CPP14_FEATURES |
| #include <future> |
| #include <mutex> |
| #include <shared_mutex> |
| #include <thread> |
| #endif |
| |
| /******************************************************************************/ |
| |
| /* |
| * Summary: |
| * |
| * This code tests the behavior of time-related functions in the presence of |
| * system clock changes (jumps). It requires root/Administrator privileges in |
| * order to run because it changes the system clock. NTP should also be disabled |
| * while running this code so that NTP can't change the system clock. |
| * |
| * Each function to be tested is executed five times. The amount of time the |
| * function waits before returning is measured against the amount of time the |
| * function was expected to wait. If the difference exceeds a threshold value |
| * (defined below) then the test fails. |
| * |
| * The following values are intentially: |
| * - more than 200 milliseconds |
| * - more than 200 milliseconds apart |
| * - not a multiple of 100 milliseconds |
| * - not a multiple of each other |
| * - don't sum or diff to a multiple of 100 milliseconds |
| */ |
| const long long s_waitMs = 580; |
| const long long s_shortJumpMs = 230; |
| const long long s_longJumpMs = 870; // Causes additional, unavoidable failures when BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC is disabled |
| const long long s_sleepBeforeJumpMs = 110; |
| |
| #ifdef _WIN32 |
| const long long s_maxEarlyErrorMs = 10 |
| + 100; // Windows is unpredictable, especially in a VM, so allow extra time if the function returns early |
| const long long s_maxLateErrorMs = 110 // due to polling, functions may not return for up to 100 milliseconds after they are supposed to |
| + 100; // Windows is slow, especially in a VM, so allow extra time for the functions to return |
| #else |
| const long long s_maxEarlyErrorMs = 10; |
| const long long s_maxLateErrorMs = 110; // Due to polling, functions may not return for up to 100 milliseconds after they are supposed to |
| #endif |
| |
| int g_numTestsRun = 0; |
| int g_numTestsPassed = 0; |
| int g_numTestsFailed = 0; |
| |
| /******************************************************************************/ |
| |
| // A custom clock based off the system clock but with a different epoch. |
| |
| namespace custom |
| { |
| class custom_boost_clock |
| { |
| public: |
| typedef boost::chrono::microseconds duration; // intentionally not nanoseconds |
| typedef duration::rep rep; |
| typedef duration::period period; |
| typedef boost::chrono::time_point<custom_boost_clock> time_point; |
| static bool is_steady; |
| |
| static time_point now(); |
| }; |
| |
| bool custom_boost_clock::is_steady = false; |
| |
| custom_boost_clock::time_point custom_boost_clock::now() |
| { |
| return time_point(boost::chrono::ceil<duration>(boost::chrono::system_clock::now().time_since_epoch()) - boost::chrono::hours(10 * 365 * 24)); |
| } |
| |
| #ifdef TEST_CPP14_FEATURES |
| class custom_std_clock |
| { |
| public: |
| typedef std::chrono::microseconds duration; // intentionally not nanoseconds |
| typedef duration::rep rep; |
| typedef duration::period period; |
| typedef std::chrono::time_point<custom_std_clock> time_point; |
| static bool is_steady; |
| |
| static time_point now(); |
| }; |
| |
| bool custom_std_clock::is_steady = false; |
| |
| custom_std_clock::time_point custom_std_clock::now() |
| { |
| return time_point(std::chrono::duration_cast<duration>(std::chrono::system_clock::now().time_since_epoch()) - std::chrono::hours(10 * 365 * 24)); |
| } |
| #endif |
| } |
| |
| /******************************************************************************/ |
| |
| template <typename MutexType = boost::mutex, typename CondType = boost::condition_variable> |
| struct BoostHelper |
| { |
| typedef MutexType mutex; |
| typedef CondType cond; |
| |
| typedef boost::lock_guard<MutexType> lock_guard; |
| typedef boost::unique_lock<MutexType> unique_lock; |
| |
| typedef boost::chrono::milliseconds milliseconds; |
| typedef boost::chrono::nanoseconds nanoseconds; |
| |
| typedef boost::chrono::system_clock system_clock; |
| typedef boost::chrono::steady_clock steady_clock; |
| typedef custom::custom_boost_clock custom_clock; |
| |
| typedef system_clock::time_point system_time_point; |
| typedef steady_clock::time_point steady_time_point; |
| typedef custom_clock::time_point custom_time_point; |
| |
| typedef boost::cv_status cv_status; |
| typedef boost::future_status future_status; |
| |
| typedef boost::packaged_task<bool> packaged_task; |
| typedef boost::future<bool> future; |
| typedef boost::shared_future<bool> shared_future; |
| |
| typedef boost::thread thread; |
| |
| static const milliseconds waitDur; |
| |
| template <typename T> |
| static void sleep_for(T d) |
| { |
| boost::this_thread::sleep_for(d); |
| } |
| |
| template <typename T> |
| static void sleep_for_no_int(T d) |
| { |
| boost::this_thread::no_interruption_point::sleep_for(d); |
| } |
| |
| template <typename T> |
| static void sleep_until(T t) |
| { |
| boost::this_thread::sleep_until(t); |
| } |
| |
| template <typename T> |
| static void sleep_until_no_int(T t) |
| { |
| boost::this_thread::no_interruption_point::sleep_until(t); |
| } |
| |
| static system_time_point systemNow() |
| { |
| return system_clock::now(); |
| } |
| |
| static steady_time_point steadyNow() |
| { |
| return steady_clock::now(); |
| } |
| |
| static custom_time_point customNow() |
| { |
| return custom_clock::now(); |
| } |
| |
| template <class ToDuration, class Rep, class Period> |
| static ToDuration duration_cast(const boost::chrono::duration<Rep, Period>& d) |
| { |
| return boost::chrono::duration_cast<ToDuration>(d); |
| } |
| |
| static milliseconds zero() |
| { |
| return milliseconds(0); |
| } |
| }; |
| |
| template <typename MutexType, typename CondType> |
| const typename BoostHelper<MutexType, CondType>::milliseconds |
| BoostHelper<MutexType, CondType>::waitDur = typename BoostHelper<MutexType, CondType>::milliseconds(s_waitMs); |
| |
| #ifdef TEST_CPP14_FEATURES |
| template <typename MutexType = std::mutex, typename CondType = std::condition_variable> |
| struct StdHelper |
| { |
| typedef MutexType mutex; |
| typedef CondType cond; |
| |
| typedef std::lock_guard<MutexType> lock_guard; |
| typedef std::unique_lock<MutexType> unique_lock; |
| |
| typedef std::chrono::milliseconds milliseconds; |
| typedef std::chrono::nanoseconds nanoseconds; |
| |
| typedef std::chrono::system_clock system_clock; |
| typedef std::chrono::steady_clock steady_clock; |
| typedef custom::custom_std_clock custom_clock; |
| |
| typedef system_clock::time_point system_time_point; |
| typedef steady_clock::time_point steady_time_point; |
| typedef custom_clock::time_point custom_time_point; |
| |
| typedef std::cv_status cv_status; |
| typedef std::future_status future_status; |
| |
| typedef std::packaged_task<bool()> packaged_task; |
| typedef std::future<bool> future; |
| typedef std::shared_future<bool> shared_future; |
| |
| typedef std::thread thread; |
| |
| static const milliseconds waitDur; |
| |
| template <typename T> |
| static void sleep_for(T d) |
| { |
| std::this_thread::sleep_for(d); |
| } |
| |
| template <typename T> |
| static void sleep_until(T t) |
| { |
| std::this_thread::sleep_until(t); |
| } |
| |
| static system_time_point systemNow() |
| { |
| return system_clock::now(); |
| } |
| |
| static steady_time_point steadyNow() |
| { |
| return steady_clock::now(); |
| } |
| |
| static custom_time_point customNow() |
| { |
| return custom_clock::now(); |
| } |
| |
| template <class ToDuration, class Rep, class Period> |
| static ToDuration duration_cast(const std::chrono::duration<Rep, Period>& d) |
| { |
| return std::chrono::duration_cast<ToDuration>(d); |
| } |
| |
| static milliseconds zero() |
| { |
| return milliseconds(0); |
| } |
| }; |
| |
| template <typename MutexType, typename CondType> |
| const typename StdHelper<MutexType, CondType>::milliseconds |
| StdHelper<MutexType, CondType>::waitDur = typename StdHelper<MutexType, CondType>::milliseconds(s_waitMs); |
| #endif |
| |
| /******************************************************************************/ |
| |
| #ifdef _WIN32 |
| |
| void changeSystemTime(long long changeMs) |
| { |
| Sleep(s_sleepBeforeJumpMs); |
| |
| SYSTEMTIME systemTime; |
| GetSystemTime(&systemTime); |
| |
| FILETIME fileTime; |
| if (!SystemTimeToFileTime(&systemTime, &fileTime)) |
| { |
| std::cout << "ERROR: Couldn't convert system time to file time" << std::endl; |
| } |
| |
| ULARGE_INTEGER largeInt; |
| largeInt.LowPart = fileTime.dwLowDateTime; |
| largeInt.HighPart = fileTime.dwHighDateTime; |
| largeInt.QuadPart += changeMs * 10000; |
| fileTime.dwLowDateTime = largeInt.LowPart; |
| fileTime.dwHighDateTime = largeInt.HighPart; |
| |
| if (!FileTimeToSystemTime(&fileTime, &systemTime)) |
| { |
| std::cout << "ERROR: Couldn't convert file time to system time" << std::endl; |
| } |
| |
| if (!SetSystemTime(&systemTime)) |
| { |
| std::cout << "ERROR: Couldn't set system time" << std::endl; |
| } |
| } |
| |
| #else |
| |
| void changeSystemTime(long long changeMs) |
| { |
| struct timespec sleepTs; |
| sleepTs.tv_sec = (s_sleepBeforeJumpMs / 1000); |
| sleepTs.tv_nsec = (s_sleepBeforeJumpMs % 1000) * 1000000; |
| nanosleep(&sleepTs, NULL); |
| |
| struct timeval tv; |
| if (gettimeofday(&tv, NULL) != 0) |
| { |
| std::cout << "ERROR: Couldn't get system time" << std::endl; |
| } |
| |
| changeMs += tv.tv_sec * 1000; |
| changeMs += tv.tv_usec / 1000; |
| tv.tv_sec = (changeMs / 1000); |
| tv.tv_usec = (changeMs % 1000) * 1000; |
| |
| if (settimeofday(&tv, NULL) != 0) |
| { |
| std::cout << "ERROR: Couldn't set system time" << std::endl; |
| } |
| } |
| |
| #endif |
| |
| enum RcEnum |
| { |
| e_no_timeout, |
| e_timeout, |
| e_failed_bad, |
| e_failed_good, |
| e_succeeded_bad, |
| e_succeeded_good, |
| e_ready_bad, |
| e_not_ready_good, |
| e_na |
| }; |
| |
| template <typename Helper> |
| void checkWaitTime(typename Helper::nanoseconds expected, typename Helper::nanoseconds actual, RcEnum rc) |
| { |
| if (expected != Helper::zero() && expected < typename Helper::milliseconds(s_sleepBeforeJumpMs)) |
| { |
| expected = typename Helper::milliseconds(s_sleepBeforeJumpMs); |
| } |
| |
| typename Helper::milliseconds expectedMs = Helper::template duration_cast<typename Helper::milliseconds>(expected); |
| typename Helper::milliseconds actualMs = Helper::template duration_cast<typename Helper::milliseconds>(actual); |
| |
| std::cout << "Expected: " << std::setw(4) << expectedMs.count() << " ms" |
| << ", Actual: " << std::setw(4) << actualMs.count() << " ms" |
| << ", Returned: "; |
| switch (rc) |
| { |
| case e_no_timeout : std::cout << "no_timeout, "; break; |
| case e_timeout : std::cout << "timeout, "; break; |
| case e_failed_bad : std::cout << "failed, "; break; |
| case e_failed_good : std::cout << "failed, "; break; |
| case e_succeeded_bad : std::cout << "succeeded, "; break; |
| case e_succeeded_good : std::cout << "succeeded, "; break; |
| case e_ready_bad : std::cout << "ready, "; break; |
| case e_not_ready_good : std::cout << "not_ready, "; break; |
| default : std::cout << "N/A, "; break; |
| } |
| |
| if (expectedMs == Helper::zero()) |
| { |
| std::cout << "FAILED: SKIPPED (test would lock up if run)"; |
| g_numTestsFailed++; |
| } |
| else if (actual < expected - typename Helper::milliseconds(s_maxEarlyErrorMs)) |
| { |
| std::cout << "FAILED: TOO SHORT"; |
| if (rc == e_timeout) // bad |
| { |
| std::cout << ", RETURNED TIMEOUT"; |
| } |
| else if (rc == e_failed_bad) |
| { |
| std::cout << ", RETURNED FAILED"; |
| } |
| else if (rc == e_succeeded_bad) |
| { |
| std::cout << ", RETURNED SUCCEEDED"; |
| } |
| else if (rc == e_ready_bad) |
| { |
| std::cout << ", RETURNED READY"; |
| } |
| g_numTestsFailed++; |
| } |
| else if (actual > expected + typename Helper::milliseconds(s_maxLateErrorMs)) |
| { |
| std::cout << "FAILED: TOO LONG"; |
| if (rc == e_no_timeout) // bad |
| { |
| std::cout << ", RETURNED NO_TIMEOUT"; |
| } |
| else if (rc == e_failed_bad) |
| { |
| std::cout << ", RETURNED FAILED"; |
| } |
| else if (rc == e_succeeded_bad) |
| { |
| std::cout << ", RETURNED SUCCEEDED"; |
| } |
| else if (rc == e_ready_bad) |
| { |
| std::cout << ", RETURNED READY"; |
| } |
| g_numTestsFailed++; |
| } |
| else if (rc == e_no_timeout) // bad |
| { |
| std::cout << "FAILED: RETURNED NO_TIMEOUT"; |
| g_numTestsFailed++; |
| } |
| else if (rc == e_failed_bad) |
| { |
| std::cout << "FAILED: RETURNED FAILED"; |
| g_numTestsFailed++; |
| } |
| else if (rc == e_succeeded_bad) |
| { |
| std::cout << "FAILED: RETURNED SUCCEEDED"; |
| g_numTestsFailed++; |
| } |
| else if (rc == e_ready_bad) |
| { |
| std::cout << "FAILED: RETURNED READY"; |
| g_numTestsFailed++; |
| } |
| else |
| { |
| std::cout << "Passed"; |
| g_numTestsPassed++; |
| } |
| std::cout << std::endl; |
| |
| g_numTestsRun++; |
| } |
| |
| void sleepForLongTime() |
| { |
| #ifdef _WIN32 |
| Sleep(10000); |
| #else |
| struct timespec ts = {5, 0}; |
| nanosleep(&ts, NULL); |
| #endif |
| } |
| |
| bool returnFalse() |
| { |
| return false; |
| } |
| |
| /******************************************************************************/ |
| |
| // Run the test in the context provided, which may be the current thread or a separate thread. |
| template <typename Helper, typename Context, typename Function> |
| void runTestInContext(Context context, Function func, const std::string name) |
| { |
| std::cout << name << ":" << std::endl; |
| |
| { |
| std::cout << " While system clock remains stable: "; |
| context(func, 0); |
| } |
| |
| { |
| std::cout << " While system clock jumps back (short): "; |
| typename Helper::thread t(boost::bind(changeSystemTime, -s_shortJumpMs)); |
| context(func, -s_shortJumpMs); |
| t.join(); |
| } |
| |
| { |
| std::cout << " While system clock jumps back (long): "; |
| typename Helper::thread t(boost::bind(changeSystemTime, -s_longJumpMs)); |
| context(func, -s_longJumpMs); |
| t.join(); |
| } |
| |
| { |
| std::cout << " While system clock jumps forward (short): "; |
| typename Helper::thread t(boost::bind(changeSystemTime, s_shortJumpMs)); |
| context(func, s_shortJumpMs); |
| t.join(); |
| } |
| |
| { |
| std::cout << " While system clock jumps forward (long): "; |
| typename Helper::thread t(boost::bind(changeSystemTime, s_longJumpMs)); |
| context(func, s_longJumpMs); |
| t.join(); |
| } |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper, typename Function> |
| void noThreadContext(Function func, const long long jumpMs) |
| { |
| func(jumpMs); |
| } |
| |
| template <typename Helper, typename Function> |
| void threadContextWithNone(Function func, const long long jumpMs) |
| { |
| typename Helper::thread t(boost::bind(func, jumpMs)); |
| t.join(); |
| } |
| |
| template <typename Helper, typename Function> |
| void threadContextWithUnique(Function func, const long long jumpMs) |
| { |
| typename Helper::mutex m; |
| typename Helper::lock_guard g(m); |
| typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
| t.join(); |
| } |
| |
| template <typename Helper, typename Function> |
| void threadContextWithShared(Function func, const long long jumpMs) |
| { |
| typename Helper::mutex m; |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
| t.join(); |
| } |
| |
| template <typename Helper, typename Function> |
| void threadContextWithUpgrade(Function func, const long long jumpMs) |
| { |
| typename Helper::mutex m; |
| boost::upgrade_lock<typename Helper::mutex> g(m); |
| typename Helper::thread t(boost::bind(func, boost::ref(m), jumpMs)); |
| t.join(); |
| } |
| |
| //-------------------------------------- |
| |
| // Run the test in the current thread. |
| template <typename Helper, typename Function> |
| void runTest(Function func, const std::string name) |
| { |
| runTestInContext<Helper>(noThreadContext<Helper, Function>, func, name); |
| } |
| |
| // Run the test in a separate thread. |
| template <typename Helper, typename Function> |
| void runTestWithNone(Function func, const std::string name) |
| { |
| runTestInContext<Helper>(threadContextWithNone<Helper, Function>, func, name); |
| } |
| |
| // Run the test in a separate thread. Pass a locked mutex to the function under test. |
| template <typename Helper, typename Function> |
| void runTestWithUnique(Function func, const std::string name) |
| { |
| runTestInContext<Helper>(threadContextWithUnique<Helper, Function>, func, name); |
| } |
| |
| // Run the test in a separate thread. Pass a shared-locked mutex to the function under test. |
| template <typename Helper, typename Function> |
| void runTestWithShared(Function func, const std::string name) |
| { |
| runTestInContext<Helper>(threadContextWithShared<Helper, Function>, func, name); |
| } |
| |
| // Run the test in a separate thread. Pass an upgrade-locked mutex to the function under test. |
| template <typename Helper, typename Function> |
| void runTestWithUpgrade(Function func, const std::string name) |
| { |
| runTestInContext<Helper>(threadContextWithUpgrade<Helper, Function>, func, name); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Sleep |
| |
| template <typename Helper> |
| void testSleepFor(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilSteady(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilSystem(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilCustom(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSleepRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| boost::this_thread::sleep(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testSleepAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| boost::this_thread::sleep(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSleepStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for()"); |
| runTestWithNone<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), steady time"); |
| runTestWithNone<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), system time"); |
| runTestWithNone<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testSleepBoost(const std::string& name) |
| { |
| testSleepStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithNone<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), relative time"); |
| runTestWithNone<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), absolute time"); |
| } |
| |
| template <typename Helper> |
| void testSleepNoThreadStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTest<Helper>(testSleepFor <Helper>, name + "::this_thread::sleep_for(), no thread"); |
| runTest<Helper>(testSleepUntilSteady<Helper>, name + "::this_thread::sleep_until(), no thread, steady time"); |
| runTest<Helper>(testSleepUntilSystem<Helper>, name + "::this_thread::sleep_until(), no thread, system time"); |
| runTest<Helper>(testSleepUntilCustom<Helper>, name + "::this_thread::sleep_until(), no thread, custom time"); |
| } |
| |
| template <typename Helper> |
| void testSleepNoThreadBoost(const std::string& name) |
| { |
| testSleepNoThreadStd<Helper>(name); |
| |
| // Boost-only functions |
| runTest<Helper>(testSleepRelative<Helper>, name + "::this_thread::sleep(), no thread, relative time"); |
| runTest<Helper>(testSleepAbsolute<Helper>, name + "::this_thread::sleep(), no thread, absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Sleep, No Interruption Point |
| |
| template <typename Helper> |
| void testSleepForNoInt(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_for_no_int(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilNoIntSteady(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until_no_int(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilNoIntSystem(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until_no_int(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| } |
| |
| template <typename Helper> |
| void testSleepUntilNoIntCustom(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| Helper::sleep_until_no_int(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| } |
| |
| //-------------------------------------- |
| |
| #ifndef SKIP_NO_INT_SLEEP |
| |
| template <typename Helper> |
| void testSleepNoIntRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| boost::this_thread::no_interruption_point::sleep(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, e_na); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testSleepNoIntAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| boost::this_thread::no_interruption_point::sleep(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, e_na); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| #endif |
| |
| //-------------------------------------- |
| |
| // Only Boost supports no_interruption_point |
| |
| template <typename Helper> |
| void testSleepNoIntBoost(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for()"); |
| runTestWithNone<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), steady time"); |
| runTestWithNone<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), system time"); |
| runTestWithNone<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), custom time"); |
| |
| #ifndef SKIP_NO_INT_SLEEP |
| runTestWithNone<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), relative time"); |
| runTestWithNone<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), absolute time"); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testSleepNoThreadNoIntBoost(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTest<Helper>(testSleepForNoInt <Helper>, name + "::this_thread::no_interruption_point::sleep_for(), no thread"); |
| runTest<Helper>(testSleepUntilNoIntSteady<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, steady time"); |
| runTest<Helper>(testSleepUntilNoIntSystem<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, system time"); |
| runTest<Helper>(testSleepUntilNoIntCustom<Helper>, name + "::this_thread::no_interruption_point::sleep_until(), no thread, custom time"); |
| |
| #ifndef SKIP_NO_INT_SLEEP |
| runTest<Helper>(testSleepNoIntRelative<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, relative time"); |
| runTest<Helper>(testSleepNoIntAbsolute<Helper>, name + "::this_thread::no_interruption_point::sleep(), no thread, absolute time"); |
| #endif |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Try Join |
| |
| template <typename Helper> |
| void testTryJoinFor(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.try_join_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryJoinUntilSteady(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.try_join_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryJoinUntilSystem(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.try_join_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryJoinUntilCustom(const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.try_join_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTimedJoinRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.timed_join(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testTimedJoinAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| typename Helper::thread t3(sleepForLongTime); |
| bool succeeded = t3.timed_join(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| // Only Boost supports timed try_join functions |
| |
| template <typename Helper> |
| void testJoinBoost(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testTryJoinFor <Helper>, name + "::thread::try_join_for()"); |
| runTestWithNone<Helper>(testTryJoinUntilSteady<Helper>, name + "::thread::try_join_until(), steady time"); |
| runTestWithNone<Helper>(testTryJoinUntilSystem<Helper>, name + "::thread::try_join_until(), system time"); |
| runTestWithNone<Helper>(testTryJoinUntilCustom<Helper>, name + "::thread::try_join_until(), custom time"); |
| runTestWithNone<Helper>(testTimedJoinRelative <Helper>, name + "::thread::timed_join(), relative time"); |
| runTestWithNone<Helper>(testTimedJoinAbsolute <Helper>, name + "::thread::timed_join(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Condition Variable Wait |
| |
| template <typename Helper> |
| void testCondVarWaitFor(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = (cv.wait_for(g, Helper::waitDur) == Helper::cv_status::no_timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilSteady(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = (cv.wait_until(g, Helper::steadyNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilSystem(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = (cv.wait_until(g, Helper::systemNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilCustom(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = (cv.wait_until(g, Helper::customNow() + Helper::waitDur) == Helper::cv_status::no_timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testCondVarTimedWaitRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = cv.timed_wait(g, ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testCondVarTimedWaitAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = cv.timed_wait(g, ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testCondVarStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testCondVarWaitFor <Helper>, name + "::wait_for()"); |
| runTestWithNone<Helper>(testCondVarWaitUntilSteady<Helper>, name + "::wait_until(), steady time"); |
| runTestWithNone<Helper>(testCondVarWaitUntilSystem<Helper>, name + "::wait_until(), system time"); |
| runTestWithNone<Helper>(testCondVarWaitUntilCustom<Helper>, name + "::wait_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testCondVarBoost(const std::string& name) |
| { |
| testCondVarStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithNone<Helper>(testCondVarTimedWaitRelative<Helper>, name + "::timed_wait(), relative time"); |
| runTestWithNone<Helper>(testCondVarTimedWaitAbsolute<Helper>, name + "::timed_wait(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Condition Variable Wait with Predicate |
| |
| template <typename Helper> |
| void testCondVarWaitForPred(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = cv.wait_for(g, Helper::waitDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilPredSteady(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = cv.wait_until(g, Helper::steadyNow() + Helper::waitDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilPredSystem(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = cv.wait_until(g, Helper::systemNow() + Helper::waitDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| template <typename Helper> |
| void testCondVarWaitUntilPredCustom(const long long jumpMs) |
| { |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool noTimeout = cv.wait_until(g, Helper::customNow() + Helper::waitDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testCondVarTimedWaitPredRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = cv.timed_wait(g, ptDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testCondVarTimedWaitPredAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::cond cv; |
| typename Helper::mutex m; |
| typename Helper::unique_lock g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = cv.timed_wait(g, ptNow + ptDur, returnFalse); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testCondVarPredStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testCondVarWaitForPred <Helper>, name + "::wait_for(), with predicate"); |
| runTestWithNone<Helper>(testCondVarWaitUntilPredSteady<Helper>, name + "::wait_until(), with predicate, steady time"); |
| runTestWithNone<Helper>(testCondVarWaitUntilPredSystem<Helper>, name + "::wait_until(), with predicate, system time"); |
| runTestWithNone<Helper>(testCondVarWaitUntilPredCustom<Helper>, name + "::wait_until(), with predicate, custom time"); |
| } |
| |
| template <typename Helper> |
| void testCondVarPredBoost(const std::string& name) |
| { |
| testCondVarPredStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithNone<Helper>(testCondVarTimedWaitPredRelative<Helper>, name + "::timed_wait(), with predicate, relative time"); |
| runTestWithNone<Helper>(testCondVarTimedWaitPredAbsolute<Helper>, name + "::timed_wait(), with predicate, absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Try Lock |
| |
| template <typename Helper> |
| void testTryLockFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTimedLockRelative(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testTimedLockAbsolute(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testMutexStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithUnique<Helper>(testTryLockFor <Helper>, name + "::try_lock_for()"); |
| runTestWithUnique<Helper>(testTryLockUntilSteady<Helper>, name + "::try_lock_until(), steady time"); |
| runTestWithUnique<Helper>(testTryLockUntilSystem<Helper>, name + "::try_lock_until(), system time"); |
| runTestWithUnique<Helper>(testTryLockUntilCustom<Helper>, name + "::try_lock_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testMutexBoost(const std::string& name) |
| { |
| testMutexStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithUnique<Helper>(testTimedLockRelative<Helper>, name + "::timed_lock(), relative time"); |
| runTestWithUnique<Helper>(testTimedLockAbsolute<Helper>, name + "::timed_lock(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Try Lock Shared |
| |
| template <typename Helper> |
| void testTryLockSharedFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_shared_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockSharedUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_shared_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockSharedUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_shared_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockSharedUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_shared_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTimedLockSharedRelative(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock_shared(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testTimedLockSharedAbsolute(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock_shared(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testMutexSharedStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithUnique<Helper>(testTryLockSharedFor <Helper>, name + "::try_lock_shared_for()"); |
| runTestWithUnique<Helper>(testTryLockSharedUntilSteady<Helper>, name + "::try_lock_shared_until(), steady time"); |
| runTestWithUnique<Helper>(testTryLockSharedUntilSystem<Helper>, name + "::try_lock_shared_until(), system time"); |
| runTestWithUnique<Helper>(testTryLockSharedUntilCustom<Helper>, name + "::try_lock_shared_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testMutexSharedBoost(const std::string& name) |
| { |
| testMutexSharedStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithUnique<Helper>(testTimedLockSharedRelative<Helper>, name + "::timed_lock_shared(), relative time"); |
| runTestWithUnique<Helper>(testTimedLockSharedAbsolute<Helper>, name + "::timed_lock_shared(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Try Lock Upgrade |
| |
| #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
| |
| template <typename Helper> |
| void testTryLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_upgrade_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_upgrade_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_lock_upgrade_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTimedLockUpgradeRelative(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock_upgrade(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testTimedLockUpgradeAbsolute(typename Helper::mutex& m, const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool succeeded = m.timed_lock_upgrade(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTryUnlockUpgradeAndLockFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::upgrade_lock<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_upgrade_and_lock_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockUpgradeAndLockUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::upgrade_lock<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockUpgradeAndLockUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::upgrade_lock<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockUpgradeAndLockUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::upgrade_lock<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_upgrade_and_lock_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUpgradeFor(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_upgrade_for(Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUpgradeUntilSteady(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::steadyNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUpgradeUntilSystem(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::systemNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| template <typename Helper> |
| void testTryUnlockSharedAndLockUpgradeUntilCustom(typename Helper::mutex& m, const long long jumpMs) |
| { |
| boost::shared_lock_guard<typename Helper::mutex> g(m); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = m.try_unlock_shared_and_lock_upgrade_until(Helper::customNow() + Helper::waitDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_bad : e_failed_good); |
| } |
| |
| #endif |
| |
| //-------------------------------------- |
| |
| // Only Boost supports upgrade mutexes |
| |
| template <typename Helper> |
| void testMutexUpgradeBoost(const std::string& name) |
| { |
| #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
| std::cout << std::endl; |
| runTestWithUnique<Helper>(testTryLockUpgradeFor <Helper>, name + "::try_lock_upgrade_for()"); |
| runTestWithUnique<Helper>(testTryLockUpgradeUntilSteady<Helper>, name + "::try_lock_upgrade_until(), steady time"); |
| runTestWithUnique<Helper>(testTryLockUpgradeUntilSystem<Helper>, name + "::try_lock_upgrade_until(), system time"); |
| runTestWithUnique<Helper>(testTryLockUpgradeUntilCustom<Helper>, name + "::try_lock_upgrade_until(), custom time"); |
| runTestWithUnique<Helper>(testTimedLockUpgradeRelative <Helper>, name + "::timed_lock_upgrade(), relative time"); |
| runTestWithUnique<Helper>(testTimedLockUpgradeAbsolute <Helper>, name + "::timed_lock_upgrade(), absolute time"); |
| |
| std::cout << std::endl; |
| runTestWithShared<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_for()"); |
| runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_until(), steady time"); |
| runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_until(), system time"); |
| runTestWithShared<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_until(), custom time"); |
| |
| std::cout << std::endl; |
| runTestWithShared<Helper>(testTryUnlockUpgradeAndLockFor <Helper>, name + "::try_unlock_upgrade_and_lock_for()"); |
| runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSteady<Helper>, name + "::try_unlock_upgrade_and_lock_until(), steady time"); |
| runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilSystem<Helper>, name + "::try_unlock_upgrade_and_lock_until(), system time"); |
| runTestWithShared<Helper>(testTryUnlockUpgradeAndLockUntilCustom<Helper>, name + "::try_unlock_upgrade_and_lock_until(), custom time"); |
| |
| std::cout << std::endl; |
| runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockFor <Helper>, name + "::try_unlock_shared_and_lock_upgrade_for()"); |
| runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSteady<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), steady time"); |
| runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilSystem<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), system time"); |
| runTestWithUpgrade<Helper>(testTryUnlockSharedAndLockUntilCustom<Helper>, name + "::try_unlock_shared_and_lock_upgrade_until(), custom time"); |
| #endif |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Future Wait |
| |
| template <typename Helper> |
| void testFutureWaitFor(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (f.wait_for(Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testFutureWaitUntilSteady(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (f.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testFutureWaitUntilSystem(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (f.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testFutureWaitUntilCustom(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (f.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testFutureTimedWaitRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = f.timed_wait(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testFutureTimedWaitAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = f.timed_wait_until(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testFutureStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testFutureWaitFor <Helper>, name + "::wait_for()"); |
| runTestWithNone<Helper>(testFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time"); |
| runTestWithNone<Helper>(testFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time"); |
| runTestWithNone<Helper>(testFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testFutureBoost(const std::string& name) |
| { |
| testFutureStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithNone<Helper>(testFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time"); |
| runTestWithNone<Helper>(testFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Shared Future Wait |
| |
| template <typename Helper> |
| void testSharedFutureWaitFor(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (sf.wait_for(Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSharedFutureWaitUntilSteady(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (sf.wait_until(Helper::steadyNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSharedFutureWaitUntilSystem(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (sf.wait_until(Helper::systemNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSharedFutureWaitUntilCustom(const long long jumpMs) |
| { |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (sf.wait_until(Helper::customNow() + Helper::waitDur) == Helper::future_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSharedFutureTimedWaitRelative(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = sf.timed_wait(ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| template <typename Helper> |
| void testSharedFutureTimedWaitAbsolute(const long long jumpMs) |
| { |
| #ifndef SKIP_DATETIME_FUNCTIONS |
| typename Helper::packaged_task pt(returnFalse); |
| typename Helper::future f = pt.get_future(); |
| typename Helper::shared_future sf = boost::move(f); |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| boost::posix_time::ptime ptNow(boost::posix_time::microsec_clock::universal_time()); |
| boost::posix_time::milliseconds ptDur(boost::chrono::duration_cast<boost::chrono::milliseconds>(Helper::waitDur).count()); |
| bool noTimeout = sf.timed_wait_until(ptNow + ptDur); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, noTimeout ? e_no_timeout : e_timeout); |
| #else |
| checkWaitTime<Helper>(Helper::zero(), Helper::zero(), e_na); |
| #endif |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSharedFutureStd(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSharedFutureWaitFor <Helper>, name + "::wait_for()"); |
| runTestWithNone<Helper>(testSharedFutureWaitUntilSteady<Helper>, name + "::wait_until(), steady time"); |
| runTestWithNone<Helper>(testSharedFutureWaitUntilSystem<Helper>, name + "::wait_until(), system time"); |
| runTestWithNone<Helper>(testSharedFutureWaitUntilCustom<Helper>, name + "::wait_until(), custom time"); |
| } |
| |
| template <typename Helper> |
| void testSharedFutureBoost(const std::string& name) |
| { |
| testSharedFutureStd<Helper>(name); |
| |
| // Boost-only functions |
| runTestWithNone<Helper>(testSharedFutureTimedWaitRelative<Helper>, name + "::timed_wait(), relative time"); |
| runTestWithNone<Helper>(testSharedFutureTimedWaitAbsolute<Helper>, name + "::timed_wait_until(), absolute time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Sync Priority Queue |
| |
| template <typename Helper> |
| void testSyncPriorityQueuePullFor(const long long jumpMs) |
| { |
| boost::sync_priority_queue<int> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncPriorityQueuePullUntilSteady(const long long jumpMs) |
| { |
| boost::sync_priority_queue<int> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncPriorityQueuePullUntilSystem(const long long jumpMs) |
| { |
| boost::sync_priority_queue<int> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncPriorityQueuePullUntilCustom(const long long jumpMs) |
| { |
| boost::sync_priority_queue<int> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| // Only Boost supports sync_priority_queue |
| |
| template <typename Helper> |
| void testSyncPriorityQueueBoost(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSyncPriorityQueuePullFor <Helper>, name + "::pull_for()"); |
| runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSteady<Helper>, name + "::pull_until(), steady time"); |
| runTestWithNone<Helper>(testSyncPriorityQueuePullUntilSystem<Helper>, name + "::pull_until(), system time"); |
| runTestWithNone<Helper>(testSyncPriorityQueuePullUntilCustom<Helper>, name + "::pull_until(), custom time"); |
| } |
| |
| /******************************************************************************/ |
| |
| // Test Sync Timed Queue |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForEmptySteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForEmptySystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForEmptyCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilEmptySteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilEmptySystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilEmptyCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool timeout = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::timeout); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, timeout ? e_timeout : e_no_timeout); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForNotReadySteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForNotReadySystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForNotReadyCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_for(Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilNotReadySteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_until(Helper::steadyNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilNotReadySystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_until(Helper::systemNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilNotReadyCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| q.push(0, typename Helper::milliseconds(10000)); // a long time |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool notReady = (q.pull_until(Helper::customNow() + Helper::waitDur, i) == boost::queue_op_status::not_ready); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, notReady ? e_not_ready_good : e_ready_bad); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForSucceedsSteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| q.push(0, Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForSucceedsSystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| q.push(0, Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullForSucceedsCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| q.push(0, Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_for(typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilSucceedsSteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| q.push(0, Helper::steadyNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_until(Helper::steadyNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilSucceedsSystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| q.push(0, Helper::systemNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_until(Helper::systemNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueuePullUntilSucceedsCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| q.push(0, Helper::customNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.pull_until(Helper::customNow() + typename Helper::milliseconds(10000), i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| //-------------------------------------- |
| |
| template <typename Helper> |
| void testSyncTimedQueueWaitPullSucceedsSteady(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::steady_clock> q; |
| q.push(0, Helper::steadyNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur, after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueueWaitPullSucceedsSystem(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::system_clock> q; |
| q.push(0, Helper::systemNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| template <typename Helper> |
| void testSyncTimedQueueWaitPullSucceedsCustom(const long long jumpMs) |
| { |
| boost::sync_timed_queue<int, typename Helper::custom_clock> q; |
| q.push(0, Helper::customNow() + Helper::waitDur); |
| int i; |
| |
| typename Helper::steady_time_point before(Helper::steadyNow()); |
| bool succeeded = (q.wait_pull(i) == boost::queue_op_status::success); |
| typename Helper::steady_time_point after(Helper::steadyNow()); |
| |
| checkWaitTime<Helper>(Helper::waitDur - typename Helper::milliseconds(jumpMs), after - before, succeeded ? e_succeeded_good : e_failed_bad); |
| } |
| |
| //-------------------------------------- |
| |
| // Only Boost supports sync_timed_queue |
| |
| template <typename Helper> |
| void testSyncTimedQueueBoost(const std::string& name) |
| { |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySteady <Helper>, name + "::pull_for(), empty, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForEmptySystem <Helper>, name + "::pull_for(), empty, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForEmptyCustom <Helper>, name + "::pull_for(), empty, custom time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySteady<Helper>, name + "::pull_until(), empty, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptySystem<Helper>, name + "::pull_until(), empty, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilEmptyCustom<Helper>, name + "::pull_until(), empty, custom time"); |
| |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySteady <Helper>, name + "::pull_for(), not ready, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadySystem <Helper>, name + "::pull_for(), not ready, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForNotReadyCustom <Helper>, name + "::pull_for(), not ready, custom time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySteady<Helper>, name + "::pull_until(), not ready, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadySystem<Helper>, name + "::pull_until(), not ready, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilNotReadyCustom<Helper>, name + "::pull_until(), not ready, custom time"); |
| |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSteady <Helper>, name + "::pull_for(), succeeds, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsSystem <Helper>, name + "::pull_for(), succeeds, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullForSucceedsCustom <Helper>, name + "::pull_for(), succeeds, custom time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSteady<Helper>, name + "::pull_until(), succeeds, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsSystem<Helper>, name + "::pull_until(), succeeds, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueuePullUntilSucceedsCustom<Helper>, name + "::pull_until(), succeeds, custom time"); |
| |
| std::cout << std::endl; |
| runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSteady<Helper>, name + "::wait_pull(), succeeds, steady time"); |
| runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsSystem<Helper>, name + "::wait_pull(), succeeds, system time"); |
| runTestWithNone<Helper>(testSyncTimedQueueWaitPullSucceedsCustom<Helper>, name + "::wait_pull(), succeeds, custom time"); |
| } |
| |
| /******************************************************************************/ |
| |
| int main() |
| { |
| std::cout << std::endl; |
| std::cout << "INFO: This test requires root/Administrator privileges in order to change the system clock." << std::endl; |
| std::cout << "INFO: Disable NTP while running this test to prevent NTP from changing the system clock." << std::endl; |
| std::cout << std::endl; |
| |
| std::cout << "BOOST_HAS_PTHREAD_DELAY_NP: "; |
| #ifdef BOOST_HAS_PTHREAD_DELAY_NP |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_HAS_NANOSLEEP: "; |
| #ifdef BOOST_HAS_NANOSLEEP |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_THREAD_SLEEP_FOR_IS_STEADY: "; |
| #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "CLOCK_MONOTONIC: "; |
| #ifdef CLOCK_MONOTONIC |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN: "; |
| #ifdef BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS: "; |
| #ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_THREAD_V2_SHARED_MUTEX: "; |
| #ifdef BOOST_THREAD_V2_SHARED_MUTEX |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << "BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC: "; |
| #ifdef BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC |
| std::cout << "YES" << std::endl; |
| #else |
| std::cout << "NO" << std::endl; |
| #endif |
| |
| std::cout << std::endl; |
| std::cout << "Wait Time: " << s_waitMs << " ms" << std::endl; |
| std::cout << "Short Jump Time: " << s_shortJumpMs << " ms" << std::endl; |
| std::cout << "Long Jump Time: " << s_longJumpMs << " ms" << std::endl; |
| std::cout << "Sleep Before Jump Time: " << s_sleepBeforeJumpMs << " ms" << std::endl; |
| std::cout << "Max Early Error: " << s_maxEarlyErrorMs << " ms" << std::endl; |
| std::cout << "Max Late Error: " << s_maxLateErrorMs << " ms" << std::endl; |
| |
| testSleepBoost <BoostHelper< > >("boost"); |
| testSleepNoIntBoost <BoostHelper< > >("boost"); |
| testSleepNoThreadBoost <BoostHelper< > >("boost"); |
| testSleepNoThreadNoIntBoost<BoostHelper< > >("boost"); |
| testJoinBoost <BoostHelper< > >("boost"); |
| testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable"); |
| testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable > >("boost::condition_variable"); |
| testCondVarBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any"); |
| testCondVarPredBoost <BoostHelper<boost::mutex, boost::condition_variable_any> >("boost::condition_variable_any"); |
| testMutexBoost <BoostHelper<boost::timed_mutex > >("boost::timed_mutex"); |
| testMutexBoost <BoostHelper<boost::recursive_timed_mutex > >("boost::recursive_timed_mutex"); |
| testMutexBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
| testMutexSharedBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
| testMutexUpgradeBoost <BoostHelper<boost::shared_mutex > >("boost::shared_mutex"); // upgrade_mutex is a typedef of shared_mutex, so no need to test upgrade_mutex |
| testFutureBoost <BoostHelper< > >("boost::future"); |
| testSharedFutureBoost <BoostHelper< > >("boost::shared_future"); |
| testSyncPriorityQueueBoost <BoostHelper< > >("boost::sync_priority_queue"); |
| testSyncTimedQueueBoost <BoostHelper< > >("boost::sync_timed_queue"); |
| |
| #ifdef TEST_CPP14_FEATURES |
| testSleepStd <StdHelper< > >("std"); |
| testSleepNoThreadStd<StdHelper< > >("std"); |
| testCondVarStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable"); |
| testCondVarPredStd <StdHelper<std::mutex, std::condition_variable > >("std::condition_variable"); |
| testCondVarStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any"); |
| testCondVarPredStd <StdHelper<std::mutex, std::condition_variable_any> >("std::condition_variable_any"); |
| testMutexStd <StdHelper<std::timed_mutex > >("std::timed_mutex"); |
| testMutexStd <StdHelper<std::recursive_timed_mutex > >("std::recursive_timed_mutex"); |
| testMutexStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex"); |
| testMutexSharedStd <StdHelper<std::shared_timed_mutex > >("std::shared_timed_mutex"); |
| testFutureStd <StdHelper< > >("std::future"); |
| testSharedFutureStd <StdHelper< > >("std::shared_future"); |
| #endif |
| |
| std::cout << std::endl; |
| std::cout << "Number of Tests Run: " << g_numTestsRun << std::endl; |
| std::cout << "Number of Tests Passed: " << g_numTestsPassed << std::endl; |
| std::cout << "Number of Tests Failed: " << g_numTestsFailed << std::endl; |
| |
| return 0; |
| } |