From a9706f07454847d0f0dc0fdbcf02f260dc7d4d9d Mon Sep 17 00:00:00 2001 From: Austin Beer Date: Tue, 19 Sep 2017 15:06:06 -0600 Subject: [PATCH] Fixed sleep(TimeDuration const& rel_time) when internal clock is not monotonic but CLOCK_MONOTONIC is available. --- include/boost/thread/pthread/timespec.hpp | 2 +- src/pthread/thread.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/include/boost/thread/pthread/timespec.hpp b/include/boost/thread/pthread/timespec.hpp index cee04ea3..8a7c819d 100644 --- a/include/boost/thread/pthread/timespec.hpp +++ b/include/boost/thread/pthread/timespec.hpp @@ -203,7 +203,7 @@ namespace boost } }; -#if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC +#if defined(CLOCK_MONOTONIC) class mono_timespec_timepoint { public: diff --git a/src/pthread/thread.cpp b/src/pthread/thread.cpp index 504230c9..4df4a915 100644 --- a/src/pthread/thread.cpp +++ b/src/pthread/thread.cpp @@ -491,11 +491,26 @@ namespace boost { void BOOST_THREAD_DECL sleep_for(const detail::timespec_duration& ts) { - const detail::internal_timespec_timepoint& ts2 = detail::internal_timespec_clock::now() + ts; mutex mx; unique_lock lock(mx); condition_variable cond; + +#if defined(CLOCK_MONOTONIC) && !defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC + const timespec maxSleepTs = {0, 100000000}; // 100 milliseconds + const detail::timespec_duration maxSleep(maxSleepTs); + + const detail::mono_timespec_timepoint& ts2 = detail::mono_timespec_clock::now() + ts; + detail::timespec_duration d = ts; + while (d > detail::timespec_duration::zero()) + { + detail::timespec_duration d100 = (std::min)(d, maxSleep); + cond.do_wait_until(lock, detail::internal_timespec_clock::now() + d100); + d = ts2 - detail::mono_timespec_clock::now(); + } +#else + const detail::internal_timespec_timepoint& ts2 = detail::internal_timespec_clock::now() + ts; while (cond.do_wait_until(lock, ts2)) {} +#endif } void BOOST_THREAD_DECL sleep_until(const detail::internal_timespec_timepoint& ts)