Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:43

0001 //  (C) Copyright Raffi Enficiaud 2019.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 //  Description : timer and elapsed types
0009 // ***************************************************************************
0010 
0011 #ifndef BOOST_TEST_UTILS_TIMER_HPP
0012 #define BOOST_TEST_UTILS_TIMER_HPP
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/cstdint.hpp>
0016 #include <utility>
0017 #include <ctime>
0018 
0019 # if defined(_WIN32) || defined(__CYGWIN__)
0020 #   define BOOST_TEST_TIMER_WINDOWS_API
0021 # elif defined(__MACH__) && defined(__APPLE__)// && !defined(CLOCK_MONOTONIC)
0022 #   // we compile for all macs the same, CLOCK_MONOTONIC introduced in 10.12
0023 #   define BOOST_TEST_TIMER_MACH_API
0024 # else
0025 #   define BOOST_TEST_TIMER_POSIX_API
0026 #   if !defined(CLOCK_MONOTONIC)
0027 #     error "CLOCK_MONOTONIC not defined"
0028 #   endif
0029 # endif
0030 
0031 # if defined(BOOST_TEST_TIMER_WINDOWS_API)
0032 #   include <windows.h>
0033 # elif defined(BOOST_TEST_TIMER_MACH_API)
0034 #   include <mach/mach_time.h>
0035 //#   include <mach/mach.h>      /* host_get_clock_service, mach_... */
0036 # else
0037 #   include <sys/time.h>
0038 # endif
0039 
0040 # ifdef BOOST_NO_STDC_NAMESPACE
0041   namespace std { using ::clock_t; using ::clock; }
0042 # endif
0043 
0044 namespace boost {
0045 namespace unit_test {
0046 namespace timer {
0047 
0048   struct elapsed_time
0049   {
0050     typedef boost::int_least64_t nanosecond_type;
0051 
0052     nanosecond_type wall;
0053     nanosecond_type system;
0054     void clear() {
0055       wall = 0;
0056       system = 0;
0057     }
0058   };
0059 
0060   inline double
0061   microsecond_wall_time( elapsed_time const& elapsed )
0062   {
0063       return elapsed.wall / 1E3;
0064   }
0065 
0066   inline double
0067   second_wall_time( elapsed_time const& elapsed )
0068   {
0069       return elapsed.wall / 1E9;
0070   }
0071 
0072   namespace details {
0073     #if defined(BOOST_TEST_TIMER_WINDOWS_API)
0074     elapsed_time::nanosecond_type get_tick_freq() {
0075         LARGE_INTEGER freq;
0076         ::QueryPerformanceFrequency( &freq );
0077         return static_cast<elapsed_time::nanosecond_type>(freq.QuadPart);
0078     }
0079     #elif defined(BOOST_TEST_TIMER_MACH_API)
0080     std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type> get_time_base() {
0081         mach_timebase_info_data_t timebase;
0082         if(mach_timebase_info(&timebase) == 0)
0083             return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(timebase.numer, timebase.denom);
0084         return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(0, 1);
0085     }
0086     #endif
0087   }
0088 
0089   //! Simple timing class
0090   //!
0091   //! This class measures the wall clock time.
0092   class timer
0093   {
0094   public:
0095     timer()
0096     {
0097         restart();
0098     }
0099     void restart()
0100     {
0101         _start_time_clock = std::clock();
0102     #if defined(BOOST_TEST_TIMER_WINDOWS_API)
0103         ::QueryPerformanceCounter(&_start_time_wall);
0104     #elif defined(BOOST_TEST_TIMER_MACH_API)
0105         _start_time_wall = mach_absolute_time();
0106     #else
0107         if( ::clock_gettime( CLOCK_MONOTONIC, &_start_time_wall ) != 0 )
0108         {
0109             _start_time_wall.tv_nsec = -1;
0110             _start_time_wall.tv_sec = -1;
0111         }
0112     #endif
0113     }
0114 
0115     // return elapsed time in seconds
0116     elapsed_time elapsed() const
0117     {
0118       typedef elapsed_time::nanosecond_type nanosecond_type;
0119       static const double clock_to_nano_seconds = 1E9 / CLOCKS_PER_SEC;
0120       elapsed_time return_value;
0121 
0122       // processor / system time
0123       return_value.system = static_cast<nanosecond_type>(double(std::clock() - _start_time_clock) * clock_to_nano_seconds);
0124 
0125 #if defined(BOOST_TEST_TIMER_WINDOWS_API)
0126       static const nanosecond_type tick_per_sec = details::get_tick_freq();
0127       LARGE_INTEGER end_time;
0128       ::QueryPerformanceCounter(&end_time);
0129       return_value.wall = static_cast<nanosecond_type>(((end_time.QuadPart - _start_time_wall.QuadPart) * 1E9) / tick_per_sec);
0130 #elif defined(BOOST_TEST_TIMER_MACH_API)
0131       static std::pair<nanosecond_type, nanosecond_type> timebase = details::get_time_base();
0132       nanosecond_type clock = mach_absolute_time() - _start_time_wall;
0133       return_value.wall = static_cast<nanosecond_type>((clock * timebase.first) / timebase.second);
0134 #else
0135       struct timespec end_time;
0136       return_value.wall = 0;
0137       if( ::clock_gettime( CLOCK_MONOTONIC, &end_time ) == 0 )
0138       {
0139           return_value.wall = static_cast<nanosecond_type>((end_time.tv_sec - _start_time_wall.tv_sec) * 1E9 + (end_time.tv_nsec - _start_time_wall.tv_nsec));
0140       }
0141 #endif
0142 
0143       return return_value;
0144     }
0145 
0146    private:
0147       std::clock_t _start_time_clock;
0148     #if defined(BOOST_TEST_TIMER_WINDOWS_API)
0149       LARGE_INTEGER _start_time_wall;
0150     #elif defined(BOOST_TEST_TIMER_MACH_API)
0151       elapsed_time::nanosecond_type _start_time_wall;
0152     #else
0153       struct timespec _start_time_wall;
0154     #endif
0155   };
0156 
0157 
0158 //____________________________________________________________________________//
0159 
0160 } // namespace timer
0161 } // namespace unit_test
0162 } // namespace boost
0163 
0164 #endif // BOOST_TEST_UTILS_TIMER_HPP
0165