Chris@16: // boost/chrono/system_clocks.hpp --------------------------------------------------------------// Chris@16: Chris@16: // Copyright 2008 Howard Hinnant Chris@16: // Copyright 2008 Beman Dawes Chris@16: // Copyright 2009-2011 Vicente J. Botet Escriba Chris@16: Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // See http://www.boost.org/LICENSE_1_0.txt Chris@16: Chris@16: /* Chris@16: Chris@16: This code was derived by Beman Dawes from Howard Hinnant's time2_demo prototype. Chris@16: Many thanks to Howard for making his code available under the Boost license. Chris@16: The original code was modified to conform to Boost conventions and to section Chris@16: 20.9 Time utilities [time] of the C++ committee's working paper N2798. Chris@16: See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf. Chris@16: Chris@16: time2_demo contained this comment: Chris@16: Chris@16: Much thanks to Andrei Alexandrescu, Chris@16: Walter Brown, Chris@16: Peter Dimov, Chris@16: Jeff Garland, Chris@16: Terry Golubiewski, Chris@16: Daniel Krugler, Chris@16: Anthony Williams. Chris@16: */ Chris@16: Chris@16: /* Chris@16: Chris@16: TODO: Chris@16: Chris@16: * Fully implement error handling, with test cases. Chris@16: * Consider issues raised by Michael Marcin: Chris@16: Chris@16: > In the past I've seen QueryPerformanceCounter give incorrect results, Chris@16: > especially with SpeedStep processors on laptops. This was many years ago and Chris@16: > might have been fixed by service packs and drivers. Chris@16: > Chris@16: > Typically you check the results of QPC against GetTickCount to see if the Chris@16: > results are reasonable. Chris@16: > http://support.microsoft.com/kb/274323 Chris@16: > Chris@16: > I've also heard of problems with QueryPerformanceCounter in multi-processor Chris@16: > systems. Chris@16: > Chris@16: > I know some people SetThreadAffinityMask to 1 for the current thread call Chris@16: > their QueryPerformance* functions then restore SetThreadAffinityMask. This Chris@16: > seems horrible to me because it forces your program to jump to another Chris@16: > physical processor if it isn't already on cpu0 but they claim it worked well Chris@16: > in practice because they called the timing functions infrequently. Chris@16: > Chris@16: > In the past I have chosen to use timeGetTime with timeBeginPeriod(1) for Chris@16: > high resolution timers to avoid these issues. Chris@16: Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_CHRONO_SYSTEM_CLOCKS_HPP Chris@16: #define BOOST_CHRONO_SYSTEM_CLOCKS_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: # if defined( BOOST_CHRONO_POSIX_API ) Chris@16: # if ! defined(CLOCK_REALTIME) && ! defined (__hpux__) Chris@16: # error does not supply CLOCK_REALTIME Chris@16: # endif Chris@16: # endif Chris@16: Chris@16: #ifdef BOOST_CHRONO_WINDOWS_API Chris@16: // The system_clock tick is 100 nanoseconds Chris@16: # define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::duration > Chris@16: #else Chris@16: # define BOOST_SYSTEM_CLOCK_DURATION boost::chrono::nanoseconds Chris@16: #endif Chris@16: Chris@16: // this must occur after all of the includes and before any code appears: Chris@16: #ifndef BOOST_CHRONO_HEADER_ONLY Chris@16: #include // must be the last #include Chris@16: #endif Chris@16: Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.9 Time utilities [time] // Chris@16: // synopsis // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: namespace boost { Chris@16: namespace chrono { Chris@16: Chris@16: // Clocks Chris@16: class BOOST_CHRONO_DECL system_clock; Chris@16: #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY Chris@16: class BOOST_CHRONO_DECL steady_clock; Chris@16: #endif Chris@16: Chris@16: #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY Chris@16: typedef steady_clock high_resolution_clock; // as permitted by [time.clock.hires] Chris@16: #else Chris@16: typedef system_clock high_resolution_clock; // as permitted by [time.clock.hires] Chris@16: #endif Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // // Chris@16: // 20.9.5 Clocks [time.clock] // Chris@16: // // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // If you're porting, clocks are the system-specific (non-portable) part. Chris@16: // You'll need to know how to get the current time and implement that under now(). Chris@16: // You'll need to know what units (tick period) and representation makes the most Chris@16: // sense for your clock and set those accordingly. Chris@16: // If you know how to map this clock to time_t (perhaps your clock is std::time, which Chris@16: // makes that trivial), then you can fill out system_clock's to_time_t() and from_time_t(). Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.5.1 Class system_clock [time.clock.system] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: class BOOST_CHRONO_DECL system_clock Chris@16: { Chris@16: public: Chris@16: typedef BOOST_SYSTEM_CLOCK_DURATION duration; Chris@16: typedef duration::rep rep; Chris@16: typedef duration::period period; Chris@16: typedef chrono::time_point time_point; Chris@16: BOOST_STATIC_CONSTEXPR bool is_steady = false; Chris@16: Chris@16: static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; Chris@16: #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING Chris@16: static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); Chris@16: #endif Chris@16: Chris@16: static BOOST_CHRONO_INLINE std::time_t to_time_t(const time_point& t) BOOST_NOEXCEPT; Chris@16: static BOOST_CHRONO_INLINE time_point from_time_t(std::time_t t) BOOST_NOEXCEPT; Chris@16: }; Chris@16: Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.5.2 Class steady_clock [time.clock.steady] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // As permitted by [time.clock.steady] Chris@16: // The class steady_clock is conditionally supported. Chris@16: Chris@16: #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY Chris@16: class BOOST_CHRONO_DECL steady_clock Chris@16: { Chris@16: public: Chris@16: typedef nanoseconds duration; Chris@16: typedef duration::rep rep; Chris@16: typedef duration::period period; Chris@16: typedef chrono::time_point time_point; Chris@16: BOOST_STATIC_CONSTEXPR bool is_steady = true; Chris@16: Chris@16: static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; Chris@16: #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING Chris@16: static BOOST_CHRONO_INLINE time_point now(system::error_code & ec); Chris@16: #endif Chris@16: }; Chris@16: #endif Chris@16: //----------------------------------------------------------------------------// Chris@16: // 20.9.5.3 Class high_resolution_clock [time.clock.hires] // Chris@16: //----------------------------------------------------------------------------// Chris@16: Chris@16: // As permitted, steady_clock or system_clock is a typedef for high_resolution_clock. Chris@16: // See synopsis. Chris@16: Chris@16: Chris@16: template Chris@16: struct clock_string Chris@16: { Chris@16: static std::basic_string name() Chris@16: { Chris@16: static const CharT u[] = Chris@16: { 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; Chris@16: static const std::basic_string str(u, u + sizeof(u) Chris@16: / sizeof(u[0])); Chris@16: return str; Chris@16: } Chris@16: static std::basic_string since() Chris@16: { Chris@16: static const CharT Chris@16: u[] = Chris@16: { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'J', 'a', 'n', ' ', '1', ',', ' ', '1', '9', '7', '0' }; Chris@16: static const std::basic_string str(u, u + sizeof(u) Chris@16: / sizeof(u[0])); Chris@16: return str; Chris@16: } Chris@16: }; Chris@16: Chris@16: #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY Chris@16: Chris@16: template Chris@16: struct clock_string Chris@16: { Chris@16: static std::basic_string name() Chris@16: { Chris@16: static const CharT Chris@16: u[] = Chris@16: { 's', 't', 'e', 'a', 'd', 'y', '_', 'c', 'l', 'o', 'c', 'k' }; Chris@16: static const std::basic_string str(u, u + sizeof(u) Chris@16: / sizeof(u[0])); Chris@16: return str; Chris@16: } Chris@16: static std::basic_string since() Chris@16: { Chris@16: const CharT u[] = Chris@16: { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't' }; Chris@16: const std::basic_string str(u, u + sizeof(u) / sizeof(u[0])); Chris@16: return str; Chris@16: } Chris@16: }; Chris@16: Chris@16: #endif Chris@16: Chris@16: } // namespace chrono Chris@16: } // namespace boost Chris@16: Chris@16: #ifndef BOOST_CHRONO_HEADER_ONLY Chris@16: // the suffix header occurs after all of our code: Chris@16: #include // pops abi_prefix.hpp pragmas Chris@16: #else Chris@16: #include Chris@16: #endif Chris@16: Chris@16: #endif // BOOST_CHRONO_SYSTEM_CLOCKS_HPP