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> |
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> |
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 |
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> |
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> |
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 | #if defined BOOST_THREAD_HAS_CONDATTR_SET_CLOCK_MONOTONIC && defined BOOST_CHRONO_HAS_CLOCK_STEADY |
95 | template <class Rep, class Period> |
96 | void sleep_for(const chrono::duration<Rep, Period>& d) |
97 | { |
98 | using namespace chrono; |
99 | if (d > duration<Rep, Period>::zero()) |
100 | { |
101 | steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d); |
102 | sleep_until(c_timeout); |
103 | } |
104 | } |
105 | |
106 | #elif defined BOOST_THREAD_SLEEP_FOR_IS_STEADY |
107 | |
108 | template <class Rep, class Period> |
109 | void sleep_for(const chrono::duration<Rep, Period>& d) |
110 | { |
111 | using namespace chrono; |
112 | if (d > duration<Rep, Period>::zero()) |
113 | { |
114 | duration<long double> Max = nanoseconds::max BOOST_PREVENT_MACRO_SUBSTITUTION (); |
115 | nanoseconds ns; |
116 | if (d < Max) |
117 | { |
118 | ns = duration_cast<nanoseconds>(d); |
119 | if (ns < d) |
120 | ++ns; |
121 | } |
122 | else |
123 | ns = nanoseconds:: max BOOST_PREVENT_MACRO_SUBSTITUTION (); |
124 | sleep_for(ns); |
125 | } |
126 | } |
127 | |
128 | template <class Duration> |
129 | inline BOOST_SYMBOL_VISIBLE |
130 | void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t) |
131 | { |
132 | using namespace chrono; |
133 | sleep_for(t - steady_clock::now()); |
134 | } |
135 | #else |
136 | template <class Rep, class Period> |
137 | void sleep_for(const chrono::duration<Rep, Period>& d) |
138 | { |
139 | using namespace chrono; |
140 | if (d > duration<Rep, Period>::zero()) |
141 | { |
142 | //system_clock::time_point c_timeout = time_point_cast<system_clock::duration>(system_clock::now() + ceil<nanoseconds>(d)); |
143 | system_clock::time_point c_timeout = system_clock::now() + ceil<system_clock::duration>(d); |
144 | sleep_until(c_timeout); |
145 | } |
146 | } |
147 | |
148 | #endif |
149 | |
150 | #endif |
151 | } |
152 | } |
153 | |
154 | |
155 | #endif |
156 | |