summaryrefslogtreecommitdiff
path: root/src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp')
-rw-r--r--src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp b/src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp
new file mode 100644
index 00000000000..49a61746c07
--- /dev/null
+++ b/src/third_party/boost-1.60.0/libs/timer/src/cpu_timer.cpp
@@ -0,0 +1,261 @@
+// boost cpu_timer.cpp ---------------------------------------------------------------//
+
+// Copyright Beman Dawes 1994-2006, 2011
+
+// 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)
+
+// See http://www.boost.org/libs/timer for documentation.
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_TIMER_SOURCE so that <boost/timer/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_TIMER_SOURCE
+
+#include <boost/timer/timer.hpp>
+#include <boost/chrono/chrono.hpp>
+#include <boost/io/ios_state.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/cerrno.hpp>
+#include <cstring>
+#include <sstream>
+#include <cassert>
+
+# if defined(BOOST_WINDOWS_API)
+# include <windows.h>
+# elif defined(BOOST_POSIX_API)
+# include <unistd.h>
+# include <sys/times.h>
+# else
+# error unknown API
+# endif
+
+using boost::timer::nanosecond_type;
+using boost::timer::cpu_times;
+using boost::system::error_code;
+
+namespace
+{
+
+ void show_time(const cpu_times& times,
+ std::ostream& os, const std::string& fmt, short places)
+ // NOTE WELL: Will truncate least-significant digits to LDBL_DIG, which may
+ // be as low as 10, although will be 15 for many common platforms.
+ {
+ if (places > 9)
+ places = 9;
+ else if (places < 0)
+ places = boost::timer::default_places;
+
+ boost::io::ios_flags_saver ifs(os);
+ boost::io::ios_precision_saver ips(os);
+ os.setf(std::ios_base::fixed, std::ios_base::floatfield);
+ os.precision(places);
+
+ const double sec = 1000000000.0L;
+ nanosecond_type total = times.system + times.user;
+ double wall_sec = static_cast<double>(times.wall) / sec;
+ double total_sec = static_cast<double>(total) / sec;
+
+ for (const char* format = fmt.c_str(); *format; ++format)
+ {
+ if (*format != '%' || !*(format+1) || !std::strchr("wustp", *(format+1)))
+ os << *format; // anything except % followed by a valid format character
+ // gets sent to the output stream
+ else
+ {
+ ++format;
+ switch (*format)
+ {
+ case 'w':
+ os << wall_sec;
+ break;
+ case 'u':
+ os << static_cast<double>(times.user) / sec;
+ break;
+ case 's':
+ os << static_cast<double>(times.system) / sec;
+ break;
+ case 't':
+ os << total_sec;
+ break;
+ case 'p':
+ os.precision(1);
+ if (wall_sec > 0.001L && total_sec > 0.001L)
+ os << (total_sec/wall_sec) * 100.0;
+ else
+ os << "n/a";
+ os.precision(places);
+ break;
+ }
+ }
+ }
+ }
+
+# if defined(BOOST_POSIX_API)
+ boost::int_least64_t tick_factor() // multiplier to convert ticks
+ // to nanoseconds; -1 if unknown
+ {
+ static boost::int_least64_t tick_factor = 0;
+ if (!tick_factor)
+ {
+ if ((tick_factor = ::sysconf(_SC_CLK_TCK)) <= 0)
+ tick_factor = -1;
+ else
+ {
+ assert(tick_factor <= 1000000000LL); // logic doesn't handle large ticks
+ tick_factor = 1000000000LL / tick_factor; // compute factor
+ if (!tick_factor)
+ tick_factor = -1;
+ }
+ }
+ return tick_factor;
+ }
+# endif
+
+ void get_cpu_times(boost::timer::cpu_times& current)
+ {
+ boost::chrono::duration<boost::int64_t, boost::nano>
+ x (boost::chrono::high_resolution_clock::now().time_since_epoch());
+ current.wall = x.count();
+
+# if defined(BOOST_WINDOWS_API)
+
+ FILETIME creation, exit;
+ if (::GetProcessTimes(::GetCurrentProcess(), &creation, &exit,
+ (LPFILETIME)&current.system, (LPFILETIME)&current.user))
+ {
+ current.user *= 100; // Windows uses 100 nanosecond ticks
+ current.system *= 100;
+ }
+ else
+ {
+ current.system = current.user = boost::timer::nanosecond_type(-1);
+ }
+# else
+ tms tm;
+ clock_t c = ::times(&tm);
+ if (c == static_cast<clock_t>(-1)) // error
+ {
+ current.system = current.user = boost::timer::nanosecond_type(-1);
+ }
+ else
+ {
+ current.system = boost::timer::nanosecond_type(tm.tms_stime + tm.tms_cstime);
+ current.user = boost::timer::nanosecond_type(tm.tms_utime + tm.tms_cutime);
+ boost::int_least64_t factor;
+ if ((factor = tick_factor()) != -1)
+ {
+ current.user *= factor;
+ current.system *= factor;
+ }
+ else
+ {
+ current.user = current.system = boost::timer::nanosecond_type(-1);
+ }
+ }
+# endif
+ }
+
+ // CAUTION: must be identical to same constant in auto_timers_construction.cpp
+ const std::string default_fmt(" %ws wall, %us user + %ss system = %ts CPU (%p%)\n");
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace timer
+ {
+ // format ------------------------------------------------------------------------//
+
+ BOOST_TIMER_DECL
+ std::string format(const cpu_times& times, short places, const std::string& fmt)
+ {
+ std::stringstream ss;
+ ss.exceptions(std::ios_base::badbit | std::ios_base::failbit);
+ show_time(times, ss, fmt, places);
+ return ss.str();
+ }
+
+ BOOST_TIMER_DECL
+ std::string format(const cpu_times& times, short places)
+ {
+ return format(times, places, default_fmt);
+ }
+
+ // cpu_timer ---------------------------------------------------------------------//
+
+ void cpu_timer::start() BOOST_NOEXCEPT
+ {
+ m_is_stopped = false;
+ get_cpu_times(m_times);
+ }
+
+ void cpu_timer::stop() BOOST_NOEXCEPT
+ {
+ if (is_stopped())
+ return;
+ m_is_stopped = true;
+
+ cpu_times current;
+ get_cpu_times(current);
+ m_times.wall = (current.wall - m_times.wall);
+ m_times.user = (current.user - m_times.user);
+ m_times.system = (current.system - m_times.system);
+ }
+
+ cpu_times cpu_timer::elapsed() const BOOST_NOEXCEPT
+ {
+ if (is_stopped())
+ return m_times;
+ cpu_times current;
+ get_cpu_times(current);
+ current.wall -= m_times.wall;
+ current.user -= m_times.user;
+ current.system -= m_times.system;
+ return current;
+ }
+
+ void cpu_timer::resume() BOOST_NOEXCEPT
+ {
+ if (is_stopped())
+ {
+ cpu_times current (m_times);
+ start();
+ m_times.wall -= current.wall;
+ m_times.user -= current.user;
+ m_times.system -= current.system;
+ }
+ }
+
+ // auto_cpu_timer ----------------------------------------------------------------//
+
+ auto_cpu_timer::auto_cpu_timer(std::ostream& os, short places) // #5
+ : m_places(places), m_os(&os), m_format(default_fmt)
+ {
+ start();
+ }
+
+ void auto_cpu_timer::report()
+ {
+ show_time(elapsed(), ostream(), format_string(), places());
+ }
+
+ auto_cpu_timer::~auto_cpu_timer()
+ {
+ if (!is_stopped())
+ {
+ stop(); // the sooner we stop(), the better
+ try
+ {
+ report();
+ }
+ catch (...) // eat any exceptions
+ {
+ }
+ }
+ }
+
+ } // namespace timer
+} // namespace boost