1// runtime_resolution.cpp ----------------------------------------------------------//
2
3// Copyright 2008 Howard Hinnant
4// Copyright 2008 Beman Dawes
5// Copyright 2009 Vicente J. Botet Escriba
6// Copyright (c) Microsoft Corporation 2014
7
8// Distributed under the Boost Software License, Version 1.0.
9// See http://www.boost.org/LICENSE_1_0.txt
10
11/*
12This code was extracted by Vicente J. Botet Escriba from Beman Dawes time2_demo.cpp which
13was derived by Beman Dawes from Howard Hinnant's time2_demo prototype.
14Many thanks to Howard for making his code available under the Boost license.
15The original code was modified to conform to Boost conventions and to section
1620.9 Time utilities [time] of the C++ committee's working paper N2798.
17See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf.
18
19time2_demo contained this comment:
20
21 Much thanks to Andrei Alexandrescu,
22 Walter Brown,
23 Peter Dimov,
24 Jeff Garland,
25 Terry Golubiewski,
26 Daniel Krugler,
27 Anthony Williams.
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
36#if defined(BOOST_CHRONO_MAC_API)
37#include <sys/time.h> //for gettimeofday and timeval
38#include <mach/mach_time.h> // mach_absolute_time, mach_timebase_info_data_t
39#endif
40
41#if defined(BOOST_CHRONO_WINDOWS_API)
42#include <windows.h>
43
44namespace
45{
46 #if defined UNDER_CE || BOOST_PLAT_WINDOWS_RUNTIME
47 // Windows CE and Windows store does not define timeval
48 struct timeval {
49 long tv_sec; /* seconds */
50 long tv_usec; /* and microseconds */
51 };
52 #endif
53
54 int gettimeofday(struct timeval * tp, void *)
55 {
56 FILETIME ft;
57 #if defined(UNDER_CE)
58 // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
59 SYSTEMTIME st;
60 ::GetSystemTime( &st );
61 ::SystemTimeToFileTime( &st, &ft );
62 #else
63 ::GetSystemTimeAsFileTime( &ft ); // never fails
64 #endif
65 long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
66 # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
67 t -= 116444736000000000LL;
68 # else
69 t -= 116444736000000000;
70 # endif
71 t /= 10; // microseconds
72 tp->tv_sec = static_cast<long>( t / 1000000UL);
73 tp->tv_usec = static_cast<long>( t % 1000000UL);
74 return 0;
75 }
76} // unnamed namespace
77
78#endif
79
80// Handle duration with resolution not known until run time
81using namespace boost::chrono;
82
83namespace runtime_resolution
84{
85
86class duration
87{
88public:
89 typedef long long rep;
90private:
91 rep rep_;
92
93 static const double ticks_per_nanosecond;
94
95public:
96 typedef boost::chrono::duration<double, boost::nano> tonanosec;
97
98 duration() {} // = default;
99 explicit duration(const rep& r) : rep_(r) {}
100
101 // conversions
102 explicit duration(const tonanosec& d)
103 : rep_(static_cast<rep>(d.count() * ticks_per_nanosecond)) {}
104
105 // explicit
106 tonanosec convert_to_nanosec() const {return tonanosec(rep_/ticks_per_nanosecond);}
107
108 // observer
109
110 rep count() const {return rep_;}
111
112 // arithmetic
113
114 duration& operator+=(const duration& d) {rep_ += d.rep_; return *this;}
115 duration& operator-=(const duration& d) {rep_ += d.rep_; return *this;}
116 duration& operator*=(rep rhs) {rep_ *= rhs; return *this;}
117 duration& operator/=(rep rhs) {rep_ /= rhs; return *this;}
118
119 duration operator+() const {return *this;}
120 duration operator-() const {return duration(-rep_);}
121 duration& operator++() {++rep_; return *this;}
122 duration operator++(int) {return duration(rep_++);}
123 duration& operator--() {--rep_; return *this;}
124 duration operator--(int) {return duration(rep_--);}
125
126 friend duration operator+(duration x, duration y) {return x += y;}
127 friend duration operator-(duration x, duration y) {return x -= y;}
128 friend duration operator*(duration x, rep y) {return x *= y;}
129 friend duration operator*(rep x, duration y) {return y *= x;}
130 friend duration operator/(duration x, rep y) {return x /= y;}
131
132 friend bool operator==(duration x, duration y) {return x.rep_ == y.rep_;}
133 friend bool operator!=(duration x, duration y) {return !(x == y);}
134 friend bool operator< (duration x, duration y) {return x.rep_ < y.rep_;}
135 friend bool operator<=(duration x, duration y) {return !(y < x);}
136 friend bool operator> (duration x, duration y) {return y < x;}
137 friend bool operator>=(duration x, duration y) {return !(x < y);}
138};
139
140static
141double
142init_duration()
143{
144#if defined(BOOST_CHRONO_WINDOWS_API)
145 return static_cast<double>(1) / 1000; // Windows FILETIME is 1 per microsec
146#elif defined(BOOST_CHRONO_MAC_API)
147 mach_timebase_info_data_t MachInfo;
148 mach_timebase_info(&MachInfo);
149 return static_cast<double>(MachInfo.denom) / MachInfo.numer;
150#elif defined(BOOST_CHRONO_POSIX_API)
151 return static_cast<double>(1) / 1000;
152#endif
153
154}
155
156const double duration::ticks_per_nanosecond = init_duration();
157
158class clock;
159
160class time_point
161{
162public:
163 typedef runtime_resolution::clock clock;
164 typedef long long rep;
165private:
166 rep rep_;
167
168
169 rep count() const {return rep_;}
170public:
171
172 time_point() : rep_(0) {}
173 explicit time_point(const duration& d)
174 : rep_(d.count()) {}
175
176 // arithmetic
177
178 time_point& operator+=(const duration& d) {rep_ += d.count(); return *this;}
179 time_point& operator-=(const duration& d) {rep_ -= d.count(); return *this;}
180
181 friend time_point operator+(time_point x, duration y) {return x += y;}
182 friend time_point operator+(duration x, time_point y) {return y += x;}
183 friend time_point operator-(time_point x, duration y) {return x -= y;}
184 friend duration operator-(time_point x, time_point y) {return duration(x.rep_ - y.rep_);}
185};
186
187
188class clock
189{
190public:
191 typedef runtime_resolution::duration::rep rep;
192 typedef runtime_resolution::duration duration;
193 typedef runtime_resolution::time_point time_point;
194
195 static time_point now()
196 {
197
198#if defined(BOOST_CHRONO_WINDOWS_API)
199 timeval tv;
200 gettimeofday( &tv, 0 );
201 return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
202
203#elif defined(BOOST_CHRONO_MAC_API)
204
205 timeval tv;
206 gettimeofday( &tv, 0 );
207 return time_point(duration((static_cast<rep>(tv.tv_sec)<<32) | tv.tv_usec));
208
209#elif defined(BOOST_CHRONO_POSIX_API)
210 timespec ts;
211 ::clock_gettime( CLOCK_REALTIME, tp: &ts );
212
213 return time_point(duration((static_cast<rep>(ts.tv_sec)<<32) | ts.tv_nsec/1000));
214
215
216#endif // POSIX
217
218 }
219};
220
221void test()
222{
223 std::cout << "runtime_resolution test\n";
224 clock::duration delay(boost::chrono::milliseconds(5));
225 clock::time_point start = clock::now();
226 while (clock::now() - start <= delay)
227 ;
228 clock::time_point stop = clock::now();
229 clock::duration elapsed = stop - start;
230 std::cout << "paused " <<
231 boost::chrono::nanoseconds(
232 boost::chrono::duration_cast<boost::chrono::nanoseconds>( fd: elapsed.convert_to_nanosec() )).count()
233 << " nanoseconds\n";
234}
235
236} // runtime_resolution
237
238
239int main()
240{
241 runtime_resolution::test();
242 return 0;
243}
244
245

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