| /*============================================================================= |
| Copyright (c) 2005-2007 Hartmut Kaiser |
| 2007, 2009 Tim Blechmann |
| |
| Distributed under the Boost Software License, Version 1.0. |
| (See accompanying file LICENSE_1_0.txt or copy at |
| http://www.boost.org/LICENSE_1_0.txt) |
| =============================================================================*/ |
| #if !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP) |
| #define BOOST_HIGH_RESOLUTION_TIMER_HPP |
| |
| #include <boost/config.hpp> |
| #include <boost/throw_exception.hpp> |
| |
| #if _POSIX_C_SOURCE >= 199309L |
| |
| #include "time.h" |
| |
| #include <stdexcept> |
| #include <limits> |
| |
| namespace boost { |
| |
| class high_resolution_timer |
| { |
| public: |
| high_resolution_timer() |
| { |
| restart(); |
| } |
| |
| void restart() |
| { |
| int status = clock_gettime(CLOCK_REALTIME, &start_time); |
| |
| if (status == -1) |
| boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); |
| } |
| |
| double elapsed() const // return elapsed time in seconds |
| { |
| struct timespec now; |
| |
| int status = clock_gettime(CLOCK_REALTIME, &now); |
| |
| if (status == -1) |
| boost::throw_exception(std::runtime_error("Couldn't get current time")); |
| |
| struct timespec diff; |
| |
| double ret_sec = double(now.tv_sec - start_time.tv_sec); |
| double ret_nsec = double(now.tv_nsec - start_time.tv_nsec); |
| |
| while (ret_nsec < 0) |
| { |
| ret_sec -= 1.0; |
| ret_nsec += 1e9; |
| } |
| |
| double ret = ret_sec + ret_nsec / 1e9; |
| |
| return ret; |
| } |
| |
| double elapsed_max() const // return estimated maximum value for elapsed() |
| { |
| return double((std::numeric_limits<double>::max)()); |
| } |
| |
| double elapsed_min() const // return minimum value for elapsed() |
| { |
| return 0.0; |
| } |
| |
| private: |
| struct timespec start_time; |
| }; |
| |
| } // namespace boost |
| |
| #elif defined(__APPLE__) |
| |
| #import <mach/mach_time.h> |
| |
| |
| namespace boost { |
| |
| class high_resolution_timer |
| { |
| public: |
| high_resolution_timer(void) |
| { |
| mach_timebase_info_data_t info; |
| |
| kern_return_t err = mach_timebase_info(&info); |
| if (err) |
| throw std::runtime_error("cannot create mach timebase info"); |
| |
| conversion_factor = (double)info.numer/(double)info.denom; |
| restart(); |
| } |
| |
| void restart() |
| { |
| start = mach_absolute_time(); |
| } |
| |
| double elapsed() const // return elapsed time in seconds |
| { |
| uint64_t now = mach_absolute_time(); |
| double duration = double(now - start) * conversion_factor; |
| |
| return duration |
| } |
| |
| double elapsed_max() const // return estimated maximum value for elapsed() |
| { |
| return double((std::numeric_limits<double>::max)()); |
| } |
| |
| double elapsed_min() const // return minimum value for elapsed() |
| { |
| return 0.0; |
| } |
| |
| private: |
| uint64_t start; |
| double conversion_factor; |
| }; |
| |
| } // namespace boost |
| |
| #elif defined(BOOST_WINDOWS) |
| |
| #include <stdexcept> |
| #include <limits> |
| #include <windows.h> |
| |
| namespace boost { |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // high_resolution_timer |
| // A timer object measures elapsed time. |
| // CAUTION: Windows only! |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| class high_resolution_timer |
| { |
| public: |
| high_resolution_timer() |
| { |
| start_time.QuadPart = 0; |
| frequency.QuadPart = 0; |
| |
| if (!QueryPerformanceFrequency(&frequency)) |
| boost::throw_exception(std::runtime_error("Couldn't acquire frequency")); |
| |
| restart(); |
| } |
| |
| void restart() |
| { |
| if (!QueryPerformanceCounter(&start_time)) |
| boost::throw_exception(std::runtime_error("Couldn't initialize start_time")); |
| } |
| |
| double elapsed() const // return elapsed time in seconds |
| { |
| LARGE_INTEGER now; |
| if (!QueryPerformanceCounter(&now)) |
| boost::throw_exception(std::runtime_error("Couldn't get current time")); |
| |
| return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart; |
| } |
| |
| double elapsed_max() const // return estimated maximum value for elapsed() |
| { |
| return (double((std::numeric_limits<LONGLONG>::max)()) |
| - double(start_time.QuadPart)) / double(frequency.QuadPart); |
| } |
| |
| double elapsed_min() const // return minimum value for elapsed() |
| { |
| return 1.0 / frequency.QuadPart; |
| } |
| |
| private: |
| LARGE_INTEGER start_time; |
| LARGE_INTEGER frequency; |
| }; |
| |
| } // namespace boost |
| |
| #else |
| |
| // For other platforms, simply fall back to boost::timer |
| #include <boost/timer.hpp> |
| #include <boost/throw_exception.hpp> |
| |
| namespace boost { |
| typedef boost::timer high_resolution_timer; |
| } |
| |
| #endif |
| |
| #endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP) |
| |