1 /*============================================================================= 2 Copyright (c) 2005-2007 Hartmut Kaiser 3 2007, 2009 Tim Blechmann 4 5 Distributed under the Boost Software License, Version 1.0. 6 (See accompanying file LICENSE_1_0.txt or copy at 7 http://www.boost.org/LICENSE_1_0.txt) 8 =============================================================================*/ 9 #if !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP) 10 # define BOOST_HIGH_RESOLUTION_TIMER_HPP 11 12 # include <boost/config.hpp> 13 # include <boost/throw_exception.hpp> 14 15 # if _POSIX_C_SOURCE >= 199309L 16 17 # include "time.h" 18 19 # include <stdexcept> 20 # include <limits> 21 22 namespace boost { 23 24 class high_resolution_timer { 25 public: high_resolution_timer()26 high_resolution_timer() { restart(); } 27 restart()28 void restart() { 29 int status = clock_gettime(CLOCK_REALTIME, &start_time); 30 31 if (status == -1) 32 boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); 33 } 34 elapsed() const35 double elapsed() const // return elapsed time in seconds 36 { 37 struct timespec now; 38 39 int status = clock_gettime(CLOCK_REALTIME, &now); 40 41 if (status == -1) 42 boost::throw_exception(std::runtime_error("Couldn't get current time")); 43 44 struct timespec diff; 45 46 double ret_sec = double(now.tv_sec - start_time.tv_sec); 47 double ret_nsec = double(now.tv_nsec - start_time.tv_nsec); 48 49 while (ret_nsec < 0) { 50 ret_sec -= 1.0; 51 ret_nsec += 1e9; 52 } 53 54 double ret = ret_sec + ret_nsec / 1e9; 55 56 return ret; 57 } 58 elapsed_max() const59 double elapsed_max() const // return estimated maximum value for elapsed() 60 { 61 return double((std::numeric_limits<double>::max)()); 62 } 63 elapsed_min() const64 double elapsed_min() const // return minimum value for elapsed() 65 { 66 return 0.0; 67 } 68 69 private: 70 struct timespec start_time; 71 }; 72 73 } // namespace boost 74 75 # elif defined(__APPLE__) 76 77 # import <mach/mach_time.h> 78 79 80 namespace boost { 81 82 class high_resolution_timer { 83 public: high_resolution_timer(void)84 high_resolution_timer(void) { 85 mach_timebase_info_data_t info; 86 87 kern_return_t err = mach_timebase_info(&info); 88 if (err) 89 throw std::runtime_error("cannot create mach timebase info"); 90 91 conversion_factor = (double)info.numer / (double)info.denom; 92 restart(); 93 } 94 restart()95 void restart() { start = mach_absolute_time(); } 96 elapsed() const97 double elapsed() const // return elapsed time in seconds 98 { 99 uint64_t now = mach_absolute_time(); 100 double duration = double(now - start) * conversion_factor; 101 102 return duration 103 } 104 elapsed_max() const105 double elapsed_max() const // return estimated maximum value for elapsed() 106 { 107 return double((std::numeric_limits<double>::max)()); 108 } 109 elapsed_min() const110 double elapsed_min() const // return minimum value for elapsed() 111 { 112 return 0.0; 113 } 114 115 private: 116 uint64_t start; 117 double conversion_factor; 118 }; 119 120 } // namespace boost 121 122 # elif defined(BOOST_WINDOWS) 123 124 # include <stdexcept> 125 # include <limits> 126 # include <windows.h> 127 128 namespace boost { 129 130 /////////////////////////////////////////////////////////////////////////////// 131 // 132 // high_resolution_timer 133 // A timer object measures elapsed time. 134 // CAUTION: Windows only! 135 // 136 /////////////////////////////////////////////////////////////////////////////// 137 class high_resolution_timer { 138 public: high_resolution_timer()139 high_resolution_timer() { 140 start_time.QuadPart = 0; 141 frequency.QuadPart = 0; 142 143 if (!QueryPerformanceFrequency(&frequency)) 144 boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); 145 146 restart(); 147 } 148 restart()149 void restart() { 150 if (!QueryPerformanceCounter(&start_time)) 151 boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); 152 } 153 elapsed() const154 double elapsed() const // return elapsed time in seconds 155 { 156 LARGE_INTEGER now; 157 if (!QueryPerformanceCounter(&now)) 158 boost::throw_exception(std::runtime_error("Couldn't get current time")); 159 160 return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart; 161 } 162 elapsed_max() const163 double elapsed_max() const // return estimated maximum value for elapsed() 164 { 165 return (double((std::numeric_limits<LONGLONG>::max)()) - double(start_time.QuadPart)) 166 / double(frequency.QuadPart); 167 } 168 elapsed_min() const169 double elapsed_min() const // return minimum value for elapsed() 170 { 171 return 1.0 / frequency.QuadPart; 172 } 173 174 private: 175 LARGE_INTEGER start_time; 176 LARGE_INTEGER frequency; 177 }; 178 179 } // namespace boost 180 181 # else 182 183 // For other platforms, simply fall back to boost::timer 184 # include <boost/timer.hpp> 185 # include <boost/throw_exception.hpp> 186 187 namespace boost { 188 typedef boost::timer high_resolution_timer; 189 } 190 191 # endif 192 193 #endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP) 194