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