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 { 26 public: high_resolution_timer()27 high_resolution_timer() 28 { 29 restart(); 30 } 31 restart()32 void restart() 33 { 34 int status = clock_gettime(CLOCK_REALTIME, &start_time); 35 36 if (status == -1) 37 boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); 38 } 39 elapsed() const40 double elapsed() const // return elapsed time in seconds 41 { 42 struct timespec now; 43 44 int status = clock_gettime(CLOCK_REALTIME, &now); 45 46 if (status == -1) 47 boost::throw_exception(std::runtime_error("Couldn't get current time")); 48 49 struct timespec diff; 50 51 double ret_sec = double(now.tv_sec - start_time.tv_sec); 52 double ret_nsec = double(now.tv_nsec - start_time.tv_nsec); 53 54 while (ret_nsec < 0) 55 { 56 ret_sec -= 1.0; 57 ret_nsec += 1e9; 58 } 59 60 double ret = ret_sec + ret_nsec / 1e9; 61 62 return ret; 63 } 64 elapsed_max() const65 double elapsed_max() const // return estimated maximum value for elapsed() 66 { 67 return double((std::numeric_limits<double>::max)()); 68 } 69 elapsed_min() const70 double elapsed_min() const // return minimum value for elapsed() 71 { 72 return 0.0; 73 } 74 75 private: 76 struct timespec start_time; 77 }; 78 79 } // namespace boost 80 81 #elif defined(__APPLE__) 82 83 #import <mach/mach_time.h> 84 85 86 namespace boost { 87 88 class high_resolution_timer 89 { 90 public: high_resolution_timer(void)91 high_resolution_timer(void) 92 { 93 mach_timebase_info_data_t info; 94 95 kern_return_t err = mach_timebase_info(&info); 96 if (err) 97 throw std::runtime_error("cannot create mach timebase info"); 98 99 conversion_factor = (double)info.numer/(double)info.denom; 100 restart(); 101 } 102 restart()103 void restart() 104 { 105 start = mach_absolute_time(); 106 } 107 elapsed() const108 double elapsed() const // return elapsed time in seconds 109 { 110 uint64_t now = mach_absolute_time(); 111 double duration = double(now - start) * conversion_factor; 112 113 return duration 114 } 115 elapsed_max() const116 double elapsed_max() const // return estimated maximum value for elapsed() 117 { 118 return double((std::numeric_limits<double>::max)()); 119 } 120 elapsed_min() const121 double elapsed_min() const // return minimum value for elapsed() 122 { 123 return 0.0; 124 } 125 126 private: 127 uint64_t start; 128 double conversion_factor; 129 }; 130 131 } // namespace boost 132 133 #elif defined(BOOST_WINDOWS) 134 135 #include <stdexcept> 136 #include <limits> 137 #include <windows.h> 138 139 namespace boost { 140 141 /////////////////////////////////////////////////////////////////////////////// 142 // 143 // high_resolution_timer 144 // A timer object measures elapsed time. 145 // CAUTION: Windows only! 146 // 147 /////////////////////////////////////////////////////////////////////////////// 148 class high_resolution_timer 149 { 150 public: high_resolution_timer()151 high_resolution_timer() 152 { 153 start_time.QuadPart = 0; 154 frequency.QuadPart = 0; 155 156 if (!QueryPerformanceFrequency(&frequency)) 157 boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); 158 159 restart(); 160 } 161 restart()162 void restart() 163 { 164 if (!QueryPerformanceCounter(&start_time)) 165 boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); 166 } 167 elapsed() const168 double elapsed() const // return elapsed time in seconds 169 { 170 LARGE_INTEGER now; 171 if (!QueryPerformanceCounter(&now)) 172 boost::throw_exception(std::runtime_error("Couldn't get current time")); 173 174 return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart; 175 } 176 elapsed_max() const177 double elapsed_max() const // return estimated maximum value for elapsed() 178 { 179 return (double((std::numeric_limits<LONGLONG>::max)()) 180 - double(start_time.QuadPart)) / double(frequency.QuadPart); 181 } 182 elapsed_min() const183 double elapsed_min() const // return minimum value for elapsed() 184 { 185 return 1.0 / frequency.QuadPart; 186 } 187 188 private: 189 LARGE_INTEGER start_time; 190 LARGE_INTEGER frequency; 191 }; 192 193 } // namespace boost 194 195 #else 196 197 // For other platforms, simply fall back to boost::timer 198 #include <boost/timer.hpp> 199 #include <boost/throw_exception.hpp> 200 201 namespace boost { 202 typedef boost::timer high_resolution_timer; 203 } 204 205 #endif 206 207 #endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP) 208 209