Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:46:48

0001 //  This code is based on Timer and Chrono code. Thanks to authors:
0002 //
0003 //  Boost.Timer:
0004 //  Copyright Beman Dawes 1994-2007, 2011
0005 //
0006 //  Boost.Chrono:
0007 //  Copyright Beman Dawes 2008
0008 //  Copyright 2009-2010 Vicente J. Botet Escriba
0009 //
0010 //  Simplified and modified to be able to support exceptionless (-fno-exceptions).
0011 //  Boost.Timer depends on Boost.Chorno wich uses boost::throw_exception.
0012 //  And Boost.Chrono DLLs don't build in Win32 as there is no 
0013 //  boost::throw_exception(std::exception const&) implementation
0014 //  in Boost.Chrono:
0015 //
0016 //  Copyright 2020 Ion Gaztanaga
0017 //
0018 //  Distributed under the Boost Software License, Version 1.0.
0019 //  See http://www.boost.org/LICENSE_1_0.txt
0020 
0021 //----------------------------------------------------------------------------//
0022 //                                Windows                                     //
0023 //----------------------------------------------------------------------------//
0024 #ifndef BOOST_MOVE_DETAIL_NSEC_CLOCK_HPP
0025 #define BOOST_MOVE_DETAIL_NSEC_CLOCK_HPP
0026 
0027 #include <boost/config.hpp>
0028 #include <boost/cstdint.hpp>
0029 #include <boost/move/detail/workaround.hpp>
0030 #include <cstdlib>
0031 
0032 
0033 #   if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
0034 #     define BOOST_MOVE_DETAIL_WINDOWS_API
0035 #   elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
0036 #     define BOOST_MOVE_DETAIL_MAC_API
0037 #   else
0038 #     define BOOST_MOVE_DETAIL_POSIX_API
0039 #   endif
0040 
0041 #if defined(BOOST_MOVE_DETAIL_WINDOWS_API)
0042 
0043 #include <cassert>
0044 
0045 #if defined( BOOST_USE_WINDOWS_H )
0046 #include <Windows.h>
0047 #else
0048 
0049 #if defined (WIN32_PLATFORM_PSPC)
0050 #define BOOST_MOVE_WINAPI_IMPORT BOOST_SYMBOL_IMPORT
0051 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM
0052 #elif defined (_WIN32_WCE)
0053 #define BOOST_MOVE_WINAPI_IMPORT
0054 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM
0055 #else
0056 #define BOOST_MOVE_WINAPI_IMPORT BOOST_SYMBOL_IMPORT
0057 #define BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM BOOST_SYMBOL_IMPORT
0058 #endif
0059 
0060 #if defined(WINAPI)
0061 #define BOOST_MOVE_WINAPI_CC WINAPI
0062 #else
0063    #if defined(_M_IX86) || defined(__i386__)
0064    #define BOOST_MOVE_WINAPI_CC __stdcall
0065    #else
0066    // On architectures other than 32-bit x86 __stdcall is ignored. Clang also issues a warning.
0067    #define BOOST_MOVE_WINAPI_CC
0068    #endif
0069 #endif
0070 
0071 
0072 extern "C" {
0073 
0074 union _LARGE_INTEGER;
0075 typedef long long QuadPart;
0076 
0077 BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM int BOOST_MOVE_WINAPI_CC
0078 QueryPerformanceCounter(::_LARGE_INTEGER* lpPerformanceCount);
0079 
0080 BOOST_MOVE_WINAPI_IMPORT_EXCEPT_WM int BOOST_MOVE_WINAPI_CC
0081 QueryPerformanceFrequency(::_LARGE_INTEGER* lpFrequency);
0082 
0083 } // extern "C"
0084 #endif
0085 
0086 
0087 namespace boost { namespace move_detail {
0088 
0089 BOOST_FORCEINLINE int QueryPerformanceCounter(long long* lpPerformanceCount)
0090 {
0091     return ::QueryPerformanceCounter(reinterpret_cast< ::_LARGE_INTEGER* >(lpPerformanceCount));
0092 }
0093 
0094 BOOST_FORCEINLINE int QueryPerformanceFrequency(long long* lpFrequency)
0095 {
0096     return ::QueryPerformanceFrequency(reinterpret_cast< ::_LARGE_INTEGER* >(lpFrequency));
0097 }
0098 
0099 
0100 template<int Dummy>
0101 struct QPFHolder
0102 {
0103    static inline double get_nsec_per_tic()
0104    {
0105       long long freq;
0106       //According to MS documentation:
0107       //"On systems that run Windows XP or later, the function will always succeed and will thus never return zero"
0108       (void)boost::move_detail::QueryPerformanceFrequency(&freq);
0109       return double(1000000000.0L / double(freq));
0110    }
0111 
0112    static const double nanosecs_per_tic;
0113 };
0114 
0115 template<int Dummy>
0116 const double QPFHolder<Dummy>::nanosecs_per_tic = get_nsec_per_tic();
0117 
0118 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0119 {
0120    double nanosecs_per_tic = QPFHolder<0>::nanosecs_per_tic;
0121    
0122    long long pcount;
0123    //According to MS documentation:
0124    //"On systems that run Windows XP or later, the function will always succeed and will thus never return zero"
0125    (void)boost::move_detail::QueryPerformanceCounter( &pcount );
0126    return static_cast<boost::uint64_t>(nanosecs_per_tic * double(pcount));
0127 }
0128 
0129 }}  //namespace boost { namespace move_detail {
0130 
0131 #elif defined(BOOST_MOVE_DETAIL_MAC_API)
0132 
0133 #include <mach/mach_time.h>  // mach_absolute_time, mach_timebase_info_data_t
0134 
0135 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0136 {
0137    boost::uint64_t count = ::mach_absolute_time();
0138 
0139    mach_timebase_info_data_t info;
0140    mach_timebase_info(&info);
0141    return static_cast<boost::uint64_t>
0142       ( static_cast<double>(count)*(static_cast<double>(info.numer) / info.denom) );
0143 }
0144 
0145 #elif defined(BOOST_MOVE_DETAIL_POSIX_API)
0146 
0147 #include <time.h>
0148 
0149 #  if defined(CLOCK_MONOTONIC_PRECISE)   //BSD
0150 #     define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC_PRECISE
0151 #  elif defined(CLOCK_MONOTONIC_RAW)     //Linux
0152 #     define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC_RAW
0153 #  elif defined(CLOCK_HIGHRES)           //Solaris
0154 #     define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_HIGHRES
0155 #  elif defined(CLOCK_MONOTONIC)         //POSIX (AIX, BSD, Linux, Solaris)
0156 #     define BOOST_MOVE_DETAIL_CLOCK_MONOTONIC CLOCK_MONOTONIC
0157 #  else
0158 #     error "No high resolution steady clock in your system, please provide a patch"
0159 #  endif
0160 
0161 inline boost::uint64_t nsec_clock() BOOST_NOEXCEPT
0162 {
0163    struct timespec count;
0164    ::clock_gettime(BOOST_MOVE_DETAIL_CLOCK_MONOTONIC, &count);
0165    boost::uint64_t r = static_cast<boost::uint64_t>(count.tv_sec);
0166    r *= 1000000000U;
0167    r += static_cast<boost::uint64_t>(count.tv_nsec);
0168    return r;
0169 }
0170 
0171 #endif  // POSIX
0172 
0173 namespace boost { namespace move_detail {
0174 
0175 typedef boost::uint64_t nanosecond_type;
0176 
0177 struct cpu_times
0178 {
0179    nanosecond_type wall;
0180    nanosecond_type user;
0181    nanosecond_type system;
0182 
0183    void clear() { wall = user = system = 0; }
0184 
0185    cpu_times()
0186    {  this->clear(); }
0187 };
0188 
0189 
0190 inline void get_cpu_times(boost::move_detail::cpu_times& current)
0191 {
0192     current.wall = nsec_clock();
0193 }
0194 
0195 
0196 class cpu_timer
0197 {
0198    public:
0199 
0200       //  constructor
0201       cpu_timer() BOOST_NOEXCEPT                                   { start(); }
0202 
0203       //  observers
0204       bool          is_stopped() const BOOST_NOEXCEPT              { return m_is_stopped; }
0205       cpu_times     elapsed() const BOOST_NOEXCEPT;  // does not stop()
0206 
0207       //  actions
0208       void          start() BOOST_NOEXCEPT;
0209       void          stop() BOOST_NOEXCEPT;
0210       void          resume() BOOST_NOEXCEPT; 
0211 
0212    private:
0213       cpu_times     m_times;
0214       bool          m_is_stopped;
0215 };
0216 
0217 
0218 //  cpu_timer  ---------------------------------------------------------------------//
0219 
0220 inline void cpu_timer::start() BOOST_NOEXCEPT
0221 {
0222    m_is_stopped = false;
0223    get_cpu_times(m_times);
0224 }
0225 
0226 inline void cpu_timer::stop() BOOST_NOEXCEPT
0227 {
0228    if (is_stopped())
0229       return;
0230    m_is_stopped = true;
0231       
0232    cpu_times current;
0233    get_cpu_times(current);
0234    m_times.wall = (current.wall - m_times.wall);
0235    m_times.user = (current.user - m_times.user);
0236    m_times.system = (current.system - m_times.system);
0237 }
0238 
0239 inline cpu_times cpu_timer::elapsed() const BOOST_NOEXCEPT
0240 {
0241    if (is_stopped())
0242       return m_times;
0243    cpu_times current;
0244    get_cpu_times(current);
0245    current.wall -= m_times.wall;
0246    current.user -= m_times.user;
0247    current.system -= m_times.system;
0248    return current;
0249 }
0250 
0251 inline void cpu_timer::resume() BOOST_NOEXCEPT
0252 {
0253    if (is_stopped())
0254    {
0255       cpu_times current (m_times);
0256       start();
0257       m_times.wall   -= current.wall;
0258       m_times.user   -= current.user;
0259       m_times.system -= current.system;
0260    }
0261 }
0262 
0263 
0264 
0265 }  // namespace move_detail
0266 }  // namespace boost
0267 
0268 #endif   //BOOST_MOVE_DETAIL_NSEC_CLOCK_HPP