• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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