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