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/*
11This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
12was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
13Many thanks to Howard for making his code available under the Boost license.
14The original code was modified to conform to Boost conventions and to section
1520.9 Time utilities [time] of the C++ committee's working paper N2798.
16See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
17
18time2_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
43namespace {
44void 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(timer: &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>(fd: d)).count();
52}
53}
54
55namespace boost {
56namespace this_thread {
57
58template <class Rep, class Period>
59void 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
68template <class Clock, class Duration>
69void 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 ";
84 ::print_time(t: st);
85 std::cout << " which is " << (st - system_clock::now()).count() << " microseconds away\n";
86 }
87}
88
89} // this_thread
90
91struct mutex {};
92
93struct 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 ";
121 ::print_time(t: st);
122 std::cout << " which is " << (st - system_clock::now()).count()
123 << " microseconds away\n";
124 return true;
125 }
126};
127
128struct 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 ";
152 ::print_time(t: st);
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
165boost::mutex m;
166boost::timed_mutex mut;
167boost::condition_variable cv;
168
169void 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(d: seconds(3));
176 this_thread::sleep_for(d: nanoseconds(300));
177 this_thread::sleep_until(t: 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(d: milliseconds(30));
181 mut.try_lock_until(t: 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, d: minutes(1)); // real code would put this in a loop
185 cv.wait_until(m, t: time_limit); // real code would put this in a loop
186 // For those who prefer floating point
187 this_thread::sleep_for(d: duration<double>(0.25));
188 this_thread::sleep_until(t: system_clock::now() + duration<double>(1.5));
189}
190
191
192
193int main()
194{
195 basic_examples();
196 return 0;
197}
198
199

source code of boost/libs/chrono/example/simulated_thread_interface_demo.cpp