]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/timer/src/cpu_timer.cpp
1 // boost cpu_timer.cpp ---------------------------------------------------------------//
3 // Copyright Beman Dawes 1994-2006, 2011
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 // See http://www.boost.org/libs/timer for documentation.
10 //--------------------------------------------------------------------------------------//
12 // define BOOST_TIMER_SOURCE so that <boost/timer/config.hpp> knows
13 // the library is being built (possibly exporting rather than importing code)
14 #define BOOST_TIMER_SOURCE
16 #include <boost/timer/timer.hpp>
17 #include <boost/chrono/chrono.hpp>
18 #include <boost/io/ios_state.hpp>
19 #include <boost/throw_exception.hpp>
20 #include <boost/cerrno.hpp>
25 # if defined(BOOST_WINDOWS_API)
27 # elif defined(BOOST_POSIX_API)
29 # include <sys/times.h>
34 using boost::timer::nanosecond_type
;
35 using boost::timer::cpu_times
;
36 using boost::system::error_code
;
41 void show_time(const cpu_times
& times
,
42 std::ostream
& os
, const std::string
& fmt
, short places
)
43 // NOTE WELL: Will truncate least-significant digits to LDBL_DIG, which may
44 // be as low as 10, although will be 15 for many common platforms.
49 places
= boost::timer::default_places
;
51 boost::io::ios_flags_saver
ifs(os
);
52 boost::io::ios_precision_saver
ips(os
);
53 os
.setf(std::ios_base::fixed
, std::ios_base::floatfield
);
56 const double sec
= 1000000000.0L;
57 nanosecond_type total
= times
.system
+ times
.user
;
58 double wall_sec
= static_cast<double>(times
.wall
) / sec
;
59 double total_sec
= static_cast<double>(total
) / sec
;
61 for (const char* format
= fmt
.c_str(); *format
; ++format
)
63 if (*format
!= '%' || !*(format
+1) || !std::strchr("wustp", *(format
+1)))
64 os
<< *format
; // anything except % followed by a valid format character
65 // gets sent to the output stream
75 os
<< static_cast<double>(times
.user
) / sec
;
78 os
<< static_cast<double>(times
.system
) / sec
;
85 if (wall_sec
> 0.001L && total_sec
> 0.001L)
86 os
<< (total_sec
/wall_sec
) * 100.0;
96 # if defined(BOOST_POSIX_API)
97 boost::int_least64_t tick_factor() // multiplier to convert ticks
98 // to nanoseconds; -1 if unknown
100 static boost::int_least64_t tick_factor
= 0;
103 if ((tick_factor
= ::sysconf(_SC_CLK_TCK
)) <= 0)
107 assert(tick_factor
<= INT64_C(1000000000)); // logic doesn't handle large ticks
108 tick_factor
= INT64_C(1000000000) / tick_factor
; // compute factor
117 void get_cpu_times(boost::timer::cpu_times
& current
)
119 boost::chrono::duration
<boost::int64_t, boost::nano
>
120 x (boost::chrono::high_resolution_clock::now().time_since_epoch());
121 current
.wall
= x
.count();
123 # if defined(BOOST_WINDOWS_API)
125 FILETIME creation
, exit
;
126 if (::GetProcessTimes(::GetCurrentProcess(), &creation
, &exit
,
127 (LPFILETIME
)¤t
.system
, (LPFILETIME
)¤t
.user
))
129 current
.user
*= 100; // Windows uses 100 nanosecond ticks
130 current
.system
*= 100;
134 current
.system
= current
.user
= boost::timer::nanosecond_type(-1);
138 clock_t c
= ::times(&tm
);
139 if (c
== static_cast<clock_t>(-1)) // error
141 current
.system
= current
.user
= boost::timer::nanosecond_type(-1);
145 current
.system
= boost::timer::nanosecond_type(tm
.tms_stime
+ tm
.tms_cstime
);
146 current
.user
= boost::timer::nanosecond_type(tm
.tms_utime
+ tm
.tms_cutime
);
147 boost::int_least64_t factor
;
148 if ((factor
= tick_factor()) != -1)
150 current
.user
*= factor
;
151 current
.system
*= factor
;
155 current
.user
= current
.system
= boost::timer::nanosecond_type(-1);
161 // CAUTION: must be identical to same constant in auto_timers_construction.cpp
162 const std::string
default_fmt(" %ws wall, %us user + %ss system = %ts CPU (%p%)\n");
164 } // unnamed namespace
170 // format ------------------------------------------------------------------------//
173 std::string
format(const cpu_times
& times
, short places
, const std::string
& fmt
)
175 std::stringstream ss
;
176 ss
.exceptions(std::ios_base::badbit
| std::ios_base::failbit
);
177 show_time(times
, ss
, fmt
, places
);
182 std::string
format(const cpu_times
& times
, short places
)
184 return format(times
, places
, default_fmt
);
187 // cpu_timer ---------------------------------------------------------------------//
189 void cpu_timer::start() BOOST_NOEXCEPT
191 m_is_stopped
= false;
192 get_cpu_times(m_times
);
195 void cpu_timer::stop() BOOST_NOEXCEPT
202 get_cpu_times(current
);
203 m_times
.wall
= (current
.wall
- m_times
.wall
);
204 m_times
.user
= (current
.user
- m_times
.user
);
205 m_times
.system
= (current
.system
- m_times
.system
);
208 cpu_times
cpu_timer::elapsed() const BOOST_NOEXCEPT
213 get_cpu_times(current
);
214 current
.wall
-= m_times
.wall
;
215 current
.user
-= m_times
.user
;
216 current
.system
-= m_times
.system
;
220 void cpu_timer::resume() BOOST_NOEXCEPT
224 cpu_times
current (m_times
);
226 m_times
.wall
-= current
.wall
;
227 m_times
.user
-= current
.user
;
228 m_times
.system
-= current
.system
;
232 // auto_cpu_timer ----------------------------------------------------------------//
234 auto_cpu_timer::auto_cpu_timer(std::ostream
& os
, short places
) // #5
235 : m_places(places
), m_os(&os
), m_format(default_fmt
)
240 void auto_cpu_timer::report()
242 show_time(elapsed(), ostream(), format_string(), places());
245 auto_cpu_timer::~auto_cpu_timer()
249 stop(); // the sooner we stop(), the better
250 #ifndef BOOST_NO_EXCEPTIONS
255 #ifndef BOOST_NO_EXCEPTIONS
257 catch (...) // eat any exceptions