]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // simulated_thread_interface_demo.cpp ----------------------------------------------------------// |
2 | ||
3 | // Copyright 2008 Howard Hinnant | |
4 | // Copyright 2008 Beman Dawes | |
5 | // Copyright 2009 Vicente J. Botet Escriba | |
6 | ||
7 | // Distributed under the Boost Software License, Version 1.0. | |
8 | // See http://www.boost.org/LICENSE_1_0.txt | |
9 | ||
10 | /* | |
11 | This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which | |
12 | was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. | |
13 | Many thanks to Howard for making his code available under the Boost license. | |
14 | The original code was modified to conform to Boost conventions and to section | |
15 | 20.9 Time utilities [time] of the C++ committee's working paper N2798. | |
16 | See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. | |
17 | ||
18 | time2_demo contained this comment: | |
19 | ||
20 | Much thanks to Andrei Alexandrescu, | |
21 | Walter Brown, | |
22 | Peter Dimov, | |
23 | Jeff Garland, | |
24 | Terry Golubiewski, | |
25 | Daniel Krugler, | |
26 | Anthony Williams. | |
27 | */ | |
28 | ||
29 | #define _CRT_SECURE_NO_WARNINGS // disable VC++ foolishness | |
30 | ||
31 | #include <boost/chrono/chrono.hpp> | |
32 | #include <boost/type_traits.hpp> | |
33 | ||
34 | #include <iostream> | |
35 | #include <ostream> | |
36 | #include <stdexcept> | |
37 | #include <climits> | |
38 | ||
39 | ////////////////////////////////////////////////////////// | |
40 | ///////////// simulated thread interface ///////////////// | |
41 | ////////////////////////////////////////////////////////// | |
42 | ||
92f5a8d4 | 43 | namespace { |
7c673cae FG |
44 | void print_time(boost::chrono::system_clock::time_point t) |
45 | { | |
46 | using namespace boost::chrono; | |
47 | time_t c_time = system_clock::to_time_t(t); | |
48 | std::tm* tmptr = std::localtime(&c_time); | |
49 | system_clock::duration d = t.time_since_epoch(); | |
50 | std::cout << tmptr->tm_hour << ':' << tmptr->tm_min << ':' << tmptr->tm_sec | |
51 | << '.' << (d - duration_cast<seconds>(d)).count(); | |
52 | } | |
53 | } | |
92f5a8d4 TL |
54 | |
55 | namespace boost { | |
7c673cae FG |
56 | namespace this_thread { |
57 | ||
58 | template <class Rep, class Period> | |
59 | void sleep_for(const boost::chrono::duration<Rep, Period>& d) | |
60 | { | |
61 | boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d); | |
62 | if (t < d) | |
63 | ++t; | |
64 | if (t > boost::chrono::microseconds(0)) | |
65 | std::cout << "sleep_for " << t.count() << " microseconds\n"; | |
66 | } | |
67 | ||
68 | template <class Clock, class Duration> | |
69 | void sleep_until(const boost::chrono::time_point<Clock, Duration>& t) | |
70 | { | |
71 | using namespace boost::chrono; | |
72 | typedef time_point<Clock, Duration> Time; | |
73 | typedef system_clock::time_point SysTime; | |
74 | if (t > Clock::now()) | |
75 | { | |
76 | typedef typename boost::common_type<typename Time::duration, | |
77 | typename SysTime::duration>::type D; | |
78 | /* auto */ D d = t - Clock::now(); | |
79 | microseconds us = duration_cast<microseconds>(d); | |
80 | if (us < d) | |
81 | ++us; | |
82 | SysTime st = system_clock::now() + us; | |
83 | std::cout << "sleep_until "; | |
92f5a8d4 | 84 | ::print_time(st); |
7c673cae FG |
85 | std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n"; |
86 | } | |
87 | } | |
88 | ||
89 | } // this_thread | |
90 | ||
91 | struct mutex {}; | |
92 | ||
93 | struct timed_mutex | |
94 | { | |
95 | bool try_lock() {std::cout << "timed_mutex::try_lock()\n"; return true;} | |
96 | ||
97 | template <class Rep, class Period> | |
98 | bool try_lock_for(const boost::chrono::duration<Rep, Period>& d) | |
99 | { | |
100 | boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d); | |
101 | if (t <= boost::chrono::microseconds(0)) | |
102 | return try_lock(); | |
103 | std::cout << "try_lock_for " << t.count() << " microseconds\n"; | |
104 | return true; | |
105 | } | |
106 | ||
107 | template <class Clock, class Duration> | |
108 | bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& t) | |
109 | { | |
110 | using namespace boost::chrono; | |
111 | typedef time_point<Clock, Duration> Time; | |
112 | typedef system_clock::time_point SysTime; | |
113 | if (t <= Clock::now()) | |
114 | return try_lock(); | |
115 | typedef typename boost::common_type<typename Time::duration, | |
116 | typename Clock::duration>::type D; | |
117 | /* auto */ D d = t - Clock::now(); | |
118 | microseconds us = duration_cast<microseconds>(d); | |
119 | SysTime st = system_clock::now() + us; | |
120 | std::cout << "try_lock_until "; | |
92f5a8d4 | 121 | ::print_time(st); |
7c673cae FG |
122 | std::cout << " which is " << (st - system_clock::now()).count() |
123 | << " microseconds away\n"; | |
124 | return true; | |
125 | } | |
126 | }; | |
127 | ||
128 | struct condition_variable | |
129 | { | |
130 | template <class Rep, class Period> | |
131 | bool wait_for(mutex&, const boost::chrono::duration<Rep, Period>& d) | |
132 | { | |
133 | boost::chrono::microseconds t = boost::chrono::duration_cast<boost::chrono::microseconds>(d); | |
134 | std::cout << "wait_for " << t.count() << " microseconds\n"; | |
135 | return true; | |
136 | } | |
137 | ||
138 | template <class Clock, class Duration> | |
139 | bool wait_until(mutex&, const boost::chrono::time_point<Clock, Duration>& t) | |
140 | { | |
141 | using namespace boost::chrono; | |
142 | typedef time_point<Clock, Duration> Time; | |
143 | typedef system_clock::time_point SysTime; | |
144 | if (t <= Clock::now()) | |
145 | return false; | |
146 | typedef typename boost::common_type<typename Time::duration, | |
147 | typename Clock::duration>::type D; | |
148 | /* auto */ D d = t - Clock::now(); | |
149 | microseconds us = duration_cast<microseconds>(d); | |
150 | SysTime st = system_clock::now() + us; | |
151 | std::cout << "wait_until "; | |
92f5a8d4 | 152 | ::print_time(st); |
7c673cae FG |
153 | std::cout << " which is " << (st - system_clock::now()).count() |
154 | << " microseconds away\n"; | |
155 | return true; | |
156 | } | |
157 | }; | |
158 | ||
159 | } | |
160 | ||
161 | ////////////////////////////////////////////////////////// | |
162 | //////////// Simple sleep and wait examples ////////////// | |
163 | ////////////////////////////////////////////////////////// | |
164 | ||
165 | boost::mutex m; | |
166 | boost::timed_mutex mut; | |
167 | boost::condition_variable cv; | |
168 | ||
169 | void basic_examples() | |
170 | { | |
171 | std::cout << "Running basic examples\n"; | |
172 | using namespace boost; | |
173 | using namespace boost::chrono; | |
174 | system_clock::time_point time_limit = system_clock::now() + seconds(4) + milliseconds(500); | |
175 | this_thread::sleep_for(seconds(3)); | |
176 | this_thread::sleep_for(nanoseconds(300)); | |
177 | this_thread::sleep_until(time_limit); | |
178 | // this_thread::sleep_for(time_limit); // desired compile-time error | |
179 | // this_thread::sleep_until(seconds(3)); // desired compile-time error | |
180 | mut.try_lock_for(milliseconds(30)); | |
181 | mut.try_lock_until(time_limit); | |
182 | // mut.try_lock_for(time_limit); // desired compile-time error | |
183 | // mut.try_lock_until(milliseconds(30)); // desired compile-time error | |
184 | cv.wait_for(m, minutes(1)); // real code would put this in a loop | |
185 | cv.wait_until(m, time_limit); // real code would put this in a loop | |
186 | // For those who prefer floating point | |
187 | this_thread::sleep_for(duration<double>(0.25)); | |
188 | this_thread::sleep_until(system_clock::now() + duration<double>(1.5)); | |
189 | } | |
190 | ||
191 | ||
192 | ||
193 | int main() | |
194 | { | |
195 | basic_examples(); | |
196 | return 0; | |
197 | } | |
198 |