Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / server / supernova / utilities / high_resolution_timer.hpp
blob9893b2441332249e0c635245604b5d5230339ffa
1 /*=============================================================================
2 Copyright (c) 2005-2007 Hartmut Kaiser
3 2007, 2009 Tim Blechmann
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
12 #include <boost/config.hpp>
13 #include <boost/throw_exception.hpp>
15 #if _POSIX_C_SOURCE >= 199309L
17 #include "time.h"
19 #include <stdexcept>
20 #include <limits>
22 namespace boost {
24 class high_resolution_timer
26 public:
27 high_resolution_timer()
29 restart();
32 void restart()
34 int status = clock_gettime(CLOCK_REALTIME, &start_time);
36 if (status == -1)
37 boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
40 double elapsed() const // return elapsed time in seconds
42 struct timespec now;
44 int status = clock_gettime(CLOCK_REALTIME, &now);
46 if (status == -1)
47 boost::throw_exception(std::runtime_error("Couldn't get current time"));
49 struct timespec diff;
51 double ret_sec = double(now.tv_sec - start_time.tv_sec);
52 double ret_nsec = double(now.tv_nsec - start_time.tv_nsec);
54 while (ret_nsec < 0)
56 ret_sec -= 1.0;
57 ret_nsec += 1e9;
60 double ret = ret_sec + ret_nsec / 1e9;
62 return ret;
65 double elapsed_max() const // return estimated maximum value for elapsed()
67 return double((std::numeric_limits<double>::max)());
70 double elapsed_min() const // return minimum value for elapsed()
72 return 0.0;
75 private:
76 struct timespec start_time;
79 } // namespace boost
81 #elif defined(__APPLE__)
83 #import <mach/mach_time.h>
86 namespace boost {
88 class high_resolution_timer
90 public:
91 high_resolution_timer(void)
93 mach_timebase_info_data_t info;
95 kern_return_t err = mach_timebase_info(&info);
96 if (err)
97 throw std::runtime_error("cannot create mach timebase info");
99 conversion_factor = (double)info.numer/(double)info.denom;
100 restart();
103 void restart()
105 start = mach_absolute_time();
108 double elapsed() const // return elapsed time in seconds
110 uint64_t now = mach_absolute_time();
111 double duration = double(now - start) * conversion_factor;
113 return duration
116 double elapsed_max() const // return estimated maximum value for elapsed()
118 return double((std::numeric_limits<double>::max)());
121 double elapsed_min() const // return minimum value for elapsed()
123 return 0.0;
126 private:
127 uint64_t start;
128 double conversion_factor;
131 } // namespace boost
133 #elif defined(BOOST_WINDOWS)
135 #include <stdexcept>
136 #include <limits>
137 #include <windows.h>
139 namespace boost {
141 ///////////////////////////////////////////////////////////////////////////////
143 // high_resolution_timer
144 // A timer object measures elapsed time.
145 // CAUTION: Windows only!
147 ///////////////////////////////////////////////////////////////////////////////
148 class high_resolution_timer
150 public:
151 high_resolution_timer()
153 start_time.QuadPart = 0;
154 frequency.QuadPart = 0;
156 if (!QueryPerformanceFrequency(&frequency))
157 boost::throw_exception(std::runtime_error("Couldn't acquire frequency"));
159 restart();
162 void restart()
164 if (!QueryPerformanceCounter(&start_time))
165 boost::throw_exception(std::runtime_error("Couldn't initialize start_time"));
168 double elapsed() const // return elapsed time in seconds
170 LARGE_INTEGER now;
171 if (!QueryPerformanceCounter(&now))
172 boost::throw_exception(std::runtime_error("Couldn't get current time"));
174 return double(now.QuadPart - start_time.QuadPart) / frequency.QuadPart;
177 double elapsed_max() const // return estimated maximum value for elapsed()
179 return (double((std::numeric_limits<LONGLONG>::max)())
180 - double(start_time.QuadPart)) / double(frequency.QuadPart);
183 double elapsed_min() const // return minimum value for elapsed()
185 return 1.0 / frequency.QuadPart;
188 private:
189 LARGE_INTEGER start_time;
190 LARGE_INTEGER frequency;
193 } // namespace boost
195 #else
197 // For other platforms, simply fall back to boost::timer
198 #include <boost/timer.hpp>
199 #include <boost/throw_exception.hpp>
201 namespace boost {
202 typedef boost::timer high_resolution_timer;
205 #endif
207 #endif // !defined(BOOST_HIGH_RESOLUTION_TIMER_HPP)