1 // Distributed under the Boost Software License, Version 1.0. (See 2 // accompanying file LICENSE_1_0.txt or copy at 3 // http://www.boost.org/LICENSE_1_0.txt) 4 // (C) Copyright 2011 Vicente J. Botet Escriba 5 6 #ifndef BOOST_THREAD_V2_THREAD_HPP 7 #define BOOST_THREAD_V2_THREAD_HPP 8 9 #include <boost/thread/detail/config.hpp> 10 #ifdef BOOST_THREAD_USES_CHRONO 11 #include <boost/chrono/system_clocks.hpp> 12 #include <boost/chrono/ceil.hpp> 13 #endif 14 #include <boost/thread/condition_variable.hpp> 15 #include <boost/thread/lock_types.hpp> 16 17 namespace boost 18 { 19 namespace this_thread 20 { 21 namespace no_interruption_point 22 { 23 #ifdef BOOST_THREAD_USES_CHRONO 24 25 template <class Clock, class Duration> sleep_until(const chrono::time_point<Clock,Duration> & t)26 void sleep_until(const chrono::time_point<Clock, Duration>& t) 27 { 28 using namespace chrono; 29 mutex mut; 30 condition_variable cv; 31 unique_lock<mutex> lk(mut); 32 while (Clock::now() < t) 33 cv.wait_until(lk, t); 34 } 35 36 #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY 37 38 template <class Rep, class Period> sleep_for(const chrono::duration<Rep,Period> & d)39 void sleep_for(const chrono::duration<Rep, Period>& d) 40 { 41 using namespace chrono; 42 if (d > duration<Rep, Period>::zero()) 43 { 44 duration<long double> Max = nanoseconds::max BOOST_PREVENT_MACRO_SUBSTITUTION (); 45 nanoseconds ns; 46 if (d < Max) 47 { 48 ns = duration_cast<nanoseconds>(d); 49 if (ns < d) 50 ++ns; 51 } 52 else 53 ns = nanoseconds:: max BOOST_PREVENT_MACRO_SUBSTITUTION (); 54 sleep_for(ns); 55 } 56 } 57 58 template <class Duration> 59 inline BOOST_SYMBOL_VISIBLE sleep_until(const chrono::time_point<chrono::steady_clock,Duration> & t)60 void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t) 61 { 62 using namespace chrono; 63 sleep_for(t - steady_clock::now()); 64 } 65 #else 66 template <class Rep, class Period> sleep_for(const chrono::duration<Rep,Period> & d)67 void sleep_for(const chrono::duration<Rep, Period>& d) 68 { 69 using namespace chrono; 70 if (d > duration<Rep, Period>::zero()) 71 { 72 steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d); 73 sleep_until(c_timeout); 74 } 75 } 76 77 #endif 78 79 #endif 80 } 81 #ifdef BOOST_THREAD_USES_CHRONO 82 83 template <class Clock, class Duration> sleep_until(const chrono::time_point<Clock,Duration> & t)84 void sleep_until(const chrono::time_point<Clock, Duration>& t) 85 { 86 using namespace chrono; 87 mutex mut; 88 condition_variable cv; 89 unique_lock<mutex> lk(mut); 90 while (Clock::now() < t) 91 cv.wait_until(lk, t); 92 } 93 94 #ifdef BOOST_THREAD_SLEEP_FOR_IS_STEADY 95 96 template <class Rep, class Period> sleep_for(const chrono::duration<Rep,Period> & d)97 void sleep_for(const chrono::duration<Rep, Period>& d) 98 { 99 using namespace chrono; 100 if (d > duration<Rep, Period>::zero()) 101 { 102 duration<long double> Max = nanoseconds::max BOOST_PREVENT_MACRO_SUBSTITUTION (); 103 nanoseconds ns; 104 if (d < Max) 105 { 106 ns = duration_cast<nanoseconds>(d); 107 if (ns < d) 108 ++ns; 109 } 110 else 111 ns = nanoseconds:: max BOOST_PREVENT_MACRO_SUBSTITUTION (); 112 sleep_for(ns); 113 } 114 } 115 116 template <class Duration> 117 inline BOOST_SYMBOL_VISIBLE sleep_until(const chrono::time_point<chrono::steady_clock,Duration> & t)118 void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t) 119 { 120 using namespace chrono; 121 sleep_for(t - steady_clock::now()); 122 } 123 #else 124 template <class Rep, class Period> sleep_for(const chrono::duration<Rep,Period> & d)125 void sleep_for(const chrono::duration<Rep, Period>& d) 126 { 127 using namespace chrono; 128 if (d > duration<Rep, Period>::zero()) 129 { 130 steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d); 131 sleep_until(c_timeout); 132 } 133 } 134 135 #endif 136 137 #endif 138 } 139 } 140 141 142 #endif 143