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