summaryrefslogtreecommitdiff
path: root/boost/thread/pthread/thread_data.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/pthread/thread_data.hpp')
-rw-r--r--boost/thread/pthread/thread_data.hpp161
1 files changed, 126 insertions, 35 deletions
diff --git a/boost/thread/pthread/thread_data.hpp b/boost/thread/pthread/thread_data.hpp
index f6575f1c22..859ccfbd2a 100644
--- a/boost/thread/pthread/thread_data.hpp
+++ b/boost/thread/pthread/thread_data.hpp
@@ -16,6 +16,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/assert.hpp>
+#include <boost/thread/detail/platform_time.hpp>
#ifdef BOOST_THREAD_USES_CHRONO
#include <boost/chrono/system_clocks.hpp>
#endif
@@ -111,8 +112,6 @@ namespace boost
pthread_t thread_handle;
boost::mutex data_mutex;
boost::condition_variable done_condition;
- boost::mutex sleep_mutex;
- boost::condition_variable sleep_condition;
bool done;
bool join_started;
bool joined;
@@ -241,66 +240,158 @@ namespace boost
namespace this_thread
{
+ void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
+
namespace hidden
{
- void BOOST_THREAD_DECL sleep_for(const timespec& ts);
- void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts);
+ inline bool always_false()
+ {
+ return false;
+ }
+ }
+
+#if defined BOOST_THREAD_USES_DATETIME
+#ifdef __DECXXX
+ /// Workaround of DECCXX issue of incorrect template substitution
+ template<>
+#endif
+ inline void sleep(system_time const& abs_time)
+ {
+ mutex mx;
+ unique_lock<mutex> lock(mx);
+ condition_variable cond;
+ cond.timed_wait(lock, abs_time, hidden::always_false);
}
+ template<typename TimeDuration>
+ void sleep(TimeDuration const& rel_time)
+ {
+ mutex mx;
+ unique_lock<mutex> lock(mx);
+ condition_variable cond;
+ cond.timed_wait(lock, rel_time, hidden::always_false);
+ }
+#endif
+
#ifdef BOOST_THREAD_USES_CHRONO
- template <class Rep, class Period>
- void sleep_for(const chrono::duration<Rep, Period>& d);
-#ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ mutex mut;
+ unique_lock<mutex> lk(mut);
+ condition_variable cv;
+ cv.wait_until(lk, t, hidden::always_false);
+ }
- inline
- void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
{
- return boost::this_thread::hidden::sleep_for(boost::detail::to_timespec(ns));
+ mutex mut;
+ unique_lock<mutex> lk(mut);
+ condition_variable cv;
+ cv.wait_for(lk, d, hidden::always_false);
}
#endif
-#endif // BOOST_THREAD_USES_CHRONO
namespace no_interruption_point
{
+#if defined BOOST_THREAD_SLEEP_FOR_IS_STEADY
+// Use pthread_delay_np or nanosleep when available
+// because they do not provide an interruption point.
+
namespace hidden
{
- void BOOST_THREAD_DECL sleep_for(const timespec& ts);
- void BOOST_THREAD_DECL sleep_until_realtime(const timespec& ts);
+ void BOOST_THREAD_DECL sleep_for_internal(const detail::platform_duration& ts);
}
- #ifdef BOOST_THREAD_USES_CHRONO
+#if defined BOOST_THREAD_USES_DATETIME
+#ifdef __DECXXX
+ /// Workaround of DECCXX issue of incorrect template substitution
+ template<>
+#endif
+ inline void sleep(system_time const& abs_time)
+ {
+ const detail::real_platform_timepoint ts(abs_time);
+ detail::platform_duration d(ts - detail::real_platform_clock::now());
+ while (d > detail::platform_duration::zero())
+ {
+ d = (std::min)(d, detail::platform_milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS));
+ hidden::sleep_for_internal(d);
+ d = ts - detail::real_platform_clock::now();
+ }
+ }
+
+ template<typename TimeDuration>
+ void sleep(TimeDuration const& rel_time)
+ {
+ hidden::sleep_for_internal(detail::platform_duration(rel_time));
+ }
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
template <class Rep, class Period>
- void sleep_for(const chrono::duration<Rep, Period>& d);
- #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ hidden::sleep_for_internal(detail::platform_duration(d));
+ }
- inline
- void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns)
+ template <class Duration>
+ void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t)
{
- return boost::this_thread::no_interruption_point::hidden::sleep_for(boost::detail::to_timespec(ns));
+ sleep_for(t - chrono::steady_clock::now());
}
- #endif
- #endif // BOOST_THREAD_USES_CHRONO
- } // no_interruption_point
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ typedef typename common_type<Duration, typename Clock::duration>::type common_duration;
+ common_duration d(t - Clock::now());
+ while (d > common_duration::zero())
+ {
+ d = (std::min)(d, common_duration(chrono::milliseconds(BOOST_THREAD_POLL_INTERVAL_MILLISECONDS)));
+ hidden::sleep_for_internal(detail::platform_duration(d));
+ d = t - Clock::now();
+ }
+ }
+#endif
- void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;
+#else // BOOST_THREAD_SLEEP_FOR_IS_STEADY
+// When pthread_delay_np and nanosleep are not available,
+// fall back to using the interruptible sleep functions.
#if defined BOOST_THREAD_USES_DATETIME
#ifdef __DECXXX
- /// Workaround of DECCXX issue of incorrect template substitution
- template<>
+ /// Workaround of DECCXX issue of incorrect template substitution
+ template<>
#endif
- inline void sleep(system_time const& abs_time)
- {
- return boost::this_thread::hidden::sleep_until_realtime(boost::detail::to_timespec(abs_time));
- }
+ inline void sleep(system_time const& abs_time)
+ {
+ this_thread::sleep(abs_time);
+ }
- template<typename TimeDuration>
- inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
- {
- this_thread::sleep(get_system_time()+rel_time);
- }
-#endif // BOOST_THREAD_USES_DATETIME
+ template<typename TimeDuration>
+ void sleep(TimeDuration const& rel_time)
+ {
+ this_thread::sleep(rel_time);
+ }
+#endif
+
+#ifdef BOOST_THREAD_USES_CHRONO
+ template <class Clock, class Duration>
+ void sleep_until(const chrono::time_point<Clock, Duration>& t)
+ {
+ this_thread::sleep_until(t);
+ }
+
+ template <class Rep, class Period>
+ void sleep_for(const chrono::duration<Rep, Period>& d)
+ {
+ this_thread::sleep_for(d);
+ }
+#endif
+
+#endif // BOOST_THREAD_SLEEP_FOR_IS_STEADY
+ } // no_interruption_point
} // this_thread
}