1// timeval_demo.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#endif
39
40#if defined(BOOST_CHRONO_WINDOWS_API)
41# include <windows.h>
42#endif
43
44#if defined(BOOST_CHRONO_WINDOWS_API)
45
46namespace
47{
48 #if defined UNDER_CE || BOOST_PLAT_WINDOWS_RUNTIME
49 // Windows CE and Windows store does not define timeval
50 struct timeval {
51 long tv_sec; /* seconds */
52 long tv_usec; /* and microseconds */
53 };
54 #endif
55
56 int gettimeofday(struct timeval * tp, void *)
57 {
58 FILETIME ft;
59 #if defined(UNDER_CE)
60 // Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
61 SYSTEMTIME st;
62 ::GetSystemTime( &st );
63 ::SystemTimeToFileTime( &st, &ft );
64 #else
65 ::GetSystemTimeAsFileTime( &ft ); // never fails
66 #endif
67 long long t = (static_cast<long long>(ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
68 # if !defined( BOOST_MSVC ) || BOOST_MSVC > 1300 // > VC++ 7.0
69 t -= 116444736000000000LL;
70 # else
71 t -= 116444736000000000;
72 # endif
73 t /= 10; // microseconds
74 tp->tv_sec = static_cast<long>( t / 1000000UL);
75 tp->tv_usec = static_cast<long>( t % 1000000UL);
76 return 0;
77 }
78} // unnamed namespace
79
80#endif
81
82// timeval clock demo
83// Demonstrate the use of a timeval-like struct to be used as the representation
84// type for both duraiton and time_point.
85
86namespace timeval_demo
87{
88
89class xtime {
90private:
91 long tv_sec;
92 long tv_usec;
93
94 void fixup() {
95 if (tv_usec < 0) {
96 tv_usec += 1000000;
97 --tv_sec;
98 }
99 }
100
101public:
102
103 explicit xtime(long sec, long usec) {
104 tv_sec = sec;
105 tv_usec = usec;
106 if (tv_usec < 0 || tv_usec >= 1000000) {
107 tv_sec += tv_usec / 1000000;
108 tv_usec %= 1000000;
109 fixup();
110 }
111 }
112
113 explicit xtime(long long usec)
114 {
115 tv_usec = static_cast<long>(usec % 1000000);
116 tv_sec = static_cast<long>(usec / 1000000);
117 fixup();
118 }
119
120 // explicit
121 operator long long() const {return static_cast<long long>(tv_sec) * 1000000 + tv_usec;}
122
123 xtime& operator += (xtime rhs) {
124 tv_sec += rhs.tv_sec;
125 tv_usec += rhs.tv_usec;
126 if (tv_usec >= 1000000) {
127 tv_usec -= 1000000;
128 ++tv_sec;
129 }
130 return *this;
131 }
132
133 xtime& operator -= (xtime rhs) {
134 tv_sec -= rhs.tv_sec;
135 tv_usec -= rhs.tv_usec;
136 fixup();
137 return *this;
138 }
139
140 xtime& operator %= (xtime rhs) {
141 long long t = tv_sec * 1000000 + tv_usec;
142 long long r = rhs.tv_sec * 1000000 + rhs.tv_usec;
143 t %= r;
144 tv_sec = static_cast<long>(t / 1000000);
145 tv_usec = static_cast<long>(t % 1000000);
146 fixup();
147 return *this;
148 }
149
150 friend xtime operator+(xtime x, xtime y) {return x += y;}
151 friend xtime operator-(xtime x, xtime y) {return x -= y;}
152 friend xtime operator%(xtime x, xtime y) {return x %= y;}
153
154 friend bool operator==(xtime x, xtime y)
155 { return (x.tv_sec == y.tv_sec && x.tv_usec == y.tv_usec); }
156
157 friend bool operator<(xtime x, xtime y) {
158 if (x.tv_sec == y.tv_sec)
159 return (x.tv_usec < y.tv_usec);
160 return (x.tv_sec < y.tv_sec);
161 }
162
163 friend bool operator!=(xtime x, xtime y) { return !(x == y); }
164 friend bool operator> (xtime x, xtime y) { return y < x; }
165 friend bool operator<=(xtime x, xtime y) { return !(y < x); }
166 friend bool operator>=(xtime x, xtime y) { return !(x < y); }
167
168 friend std::ostream& operator<<(std::ostream& os, xtime x)
169 {return os << '{' << x.tv_sec << ',' << x.tv_usec << '}';}
170};
171
172class xtime_clock
173{
174public:
175 typedef xtime rep;
176 typedef boost::micro period;
177 typedef boost::chrono::duration<rep, period> duration;
178 typedef boost::chrono::time_point<xtime_clock> time_point;
179
180 static time_point now();
181};
182
183
184xtime_clock::time_point
185xtime_clock::now()
186{
187#if defined(BOOST_CHRONO_WINDOWS_API)
188 timeval tv;
189 gettimeofday(&tv, 0);
190 xtime xt( tv.tv_sec, tv.tv_usec);
191 return time_point(duration(xt));
192
193#elif defined(BOOST_CHRONO_MAC_API)
194
195 timeval tv;
196 gettimeofday(&tv, 0);
197 xtime xt( tv.tv_sec, tv.tv_usec);
198 return time_point(duration(xt));
199
200#elif defined(BOOST_CHRONO_POSIX_API)
201 //time_point t(0,0);
202
203 timespec ts;
204 ::clock_gettime( CLOCK_REALTIME, tp: &ts );
205
206 xtime xt( ts.tv_sec, ts.tv_nsec/1000);
207 return time_point(duration(xt));
208#endif // POSIX
209
210}
211
212void test_xtime_clock()
213{
214 using namespace boost::chrono;
215 std::cout << "timeval_demo system clock test\n";
216 std::cout << "sizeof xtime_clock::time_point = " << sizeof(xtime_clock::time_point) << '\n';
217 std::cout << "sizeof xtime_clock::duration = " << sizeof(xtime_clock::duration) << '\n';
218 std::cout << "sizeof xtime_clock::rep = " << sizeof(xtime_clock::rep) << '\n';
219 xtime_clock::duration delay(milliseconds(5));
220 xtime_clock::time_point start = xtime_clock::now();
221
222 while (xtime_clock::now() - start <= delay)
223 {
224 }
225 xtime_clock::time_point stop = xtime_clock::now();
226 xtime_clock::duration elapsed = stop - start;
227 std::cout << "paused " << nanoseconds(elapsed).count() << " nanoseconds\n";
228}
229
230} // timeval_demo
231
232int main()
233{
234 timeval_demo::test_xtime_clock();
235 return 0;
236}
237
238

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