File indexing completed on 2025-01-18 09:52:43
0001
0002
0003
0004
0005
0006
0007
0008
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__)
0022 #
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
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
0090
0091
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
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
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 }
0161 }
0162 }
0163
0164 #endif
0165