1// boost/chrono/system_clocks.hpp --------------------------------------------------------------//
2
3// Copyright 2008 Howard Hinnant
4// Copyright 2008 Beman Dawes
5// Copyright 2009-2011 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
12This code was 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/*
30
31TODO:
32
33 * Fully implement error handling, with test cases.
34 * Consider issues raised by Michael Marcin:
35
36 > In the past I've seen QueryPerformanceCounter give incorrect results,
37 > especially with SpeedStep processors on laptops. This was many years ago and
38 > might have been fixed by service packs and drivers.
39 >
40 > Typically you check the results of QPC against GetTickCount to see if the
41 > results are reasonable.
42 > http://support.microsoft.com/kb/274323
43 >
44 > I've also heard of problems with QueryPerformanceCounter in multi-processor
45 > systems.
46 >
47 > I know some people SetThreadAffinityMask to 1 for the current thread call
48 > their QueryPerformance* functions then restore SetThreadAffinityMask. This
49 > seems horrible to me because it forces your program to jump to another
50 > physical processor if it isn't already on cpu0 but they claim it worked well
51 > in practice because they called the timing functions infrequently.
52 >
53 > In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for
54 > high resolution timers to avoid these issues.
55
56*/
57
58#ifndef BOOST_CHRONO_SYSTEM_CLOCKS_HPP
59#define BOOST_CHRONO_SYSTEM_CLOCKS_HPP
60
61#include <boost/chrono/config.hpp>
62#include <boost/chrono/duration.hpp>
63#include <boost/chrono/time_point.hpp>
64#include <boost/chrono/detail/system.hpp>
65#include <boost/chrono/clock_string.hpp>
66
67#include <ctime>
68
69# if defined( BOOST_CHRONO_POSIX_API )
70# if ! defined(CLOCK_REALTIME) && ! defined (__hpux__)
71# error <time.h> does not supply CLOCK_REALTIME
72# endif
73# endif
74
75#ifdef BOOST_CHRONO_WINDOWS_API
76// The system_clock tick is 100 nanoseconds
77# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::duration<boost::int_least64_t, ratio<BOOST_RATIO_INTMAX_C(1), BOOST_RATIO_INTMAX_C(10000000)> >
78#else
79# define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::nanoseconds
80#endif
81
82// this must occur after all of the includes and before any code appears:
83#ifndef BOOST_CHRONO_HEADER_ONLY
84#include <boost/config/abi_prefix.hpp> // must be the last #include
85#endif
86
87
88//----------------------------------------------------------------------------//
89// //
90// 20.9 Time utilities [time] //
91// synopsis //
92// //
93//----------------------------------------------------------------------------//
94
95namespace boost {
96namespace chrono {
97
98 // Clocks
99 class BOOST_CHRONO_DECL system_clock;
100#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
101 class BOOST_CHRONO_DECL steady_clock;
102#endif
103
104#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
105 typedef steady_clock high_resolution_clock; // as permitted by [time.clock.hires]
106#else
107 typedef system_clock high_resolution_clock; // as permitted by [time.clock.hires]
108#endif
109
110//----------------------------------------------------------------------------//
111// //
112// 20.9.5 Clocks [time.clock] //
113// //
114//----------------------------------------------------------------------------//
115
116// If you're porting, clocks are the system-specific (non-portable) part.
117// You'll need to know how to get the current time and implement that under now().
118// You'll need to know what units (tick period) and representation makes the most
119// sense for your clock and set those accordingly.
120// If you know how to map this clock to time_t (perhaps your clock is std::time, which
121// makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t().
122
123//----------------------------------------------------------------------------//
124// 20.9.5.1 Class system_clock [time.clock.system] //
125//----------------------------------------------------------------------------//
126
127 class BOOST_CHRONO_DECL system_clock
128 {
129 public:
130 typedef BOOST_SYSTEM_CLOCK_DURATION duration;
131 typedef duration::rep rep;
132 typedef duration::period period;
133 typedef chrono::time_point<system_clock> time_point;
134 BOOST_STATIC_CONSTEXPR bool is_steady = false;
135
136 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
137#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
138 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec);
139#endif
140
141 static BOOST_CHRONO_INLINE std::time_t to_time_t(const time_point& t) BOOST_NOEXCEPT;
142 static BOOST_CHRONO_INLINE time_point from_time_t(std::time_t t) BOOST_NOEXCEPT;
143 };
144
145//----------------------------------------------------------------------------//
146// 20.9.5.2 Class steady_clock [time.clock.steady] //
147//----------------------------------------------------------------------------//
148
149// As permitted by [time.clock.steady]
150// The class steady_clock is conditionally supported.
151
152#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
153 class BOOST_CHRONO_DECL steady_clock
154 {
155 public:
156 typedef nanoseconds duration;
157 typedef duration::rep rep;
158 typedef duration::period period;
159 typedef chrono::time_point<steady_clock> time_point;
160 BOOST_STATIC_CONSTEXPR bool is_steady = true;
161
162 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
163#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
164 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec);
165#endif
166 };
167#endif
168//----------------------------------------------------------------------------//
169// 20.9.5.3 Class high_resolution_clock [time.clock.hires] //
170//----------------------------------------------------------------------------//
171
172// As permitted, steady_clock or system_clock is a typedef for high_resolution_clock.
173// See synopsis.
174
175
176 template<class CharT>
177 struct clock_string<system_clock, CharT>
178 {
179 static std::basic_string<CharT> name()
180 {
181 static const CharT u[] =
182 { 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' };
183 static const std::basic_string<CharT> str(u, u + sizeof(u)
184 / sizeof(u[0]));
185 return str;
186 }
187 static std::basic_string<CharT> since()
188 {
189 static const CharT
190 u[] =
191 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'J', 'a', 'n', ' ', '1', ',', ' ', '1', '9', '7', '0' };
192 static const std::basic_string<CharT> str(u, u + sizeof(u)
193 / sizeof(u[0]));
194 return str;
195 }
196 };
197
198#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
199
200 template<class CharT>
201 struct clock_string<steady_clock, CharT>
202 {
203 static std::basic_string<CharT> name()
204 {
205 static const CharT
206 u[] =
207 { 's', 't', 'e', 'a', 'd', 'y', '_', 'c', 'l', 'o', 'c', 'k' };
208 static const std::basic_string<CharT> str(u, u + sizeof(u)
209 / sizeof(u[0]));
210 return str;
211 }
212 static std::basic_string<CharT> since()
213 {
214 const CharT u[] =
215 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't' };
216 const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0]));
217 return str;
218 }
219 };
220
221#endif
222
223} // namespace chrono
224} // namespace boost
225
226#ifndef BOOST_CHRONO_HEADER_ONLY
227// the suffix header occurs after all of our code:
228#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
229#else
230#include <boost/chrono/detail/inlined/chrono.hpp>
231#endif
232
233#endif // BOOST_CHRONO_SYSTEM_CLOCKS_HPP
234

source code of boost/boost/chrono/system_clocks.hpp