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 12 This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. 13 Many thanks to Howard for making his code available under the Boost license. 14 The original code was modified to conform to Boost conventions and to section 15 20.9 Time utilities [time] of the C++ committee's working paper N2798. 16 See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. 17 18 time2_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 31 TODO: 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 95 namespace boost { 96 namespace chrono { 97 98 // Clocks 99 class system_clock; 100 #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY 101 class 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 { nameboost::chrono::clock_string179 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 } sinceboost::chrono::clock_string187 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 { nameboost::chrono::clock_string203 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 } sinceboost::chrono::clock_string212 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