1 // boost process_cpu_clocks.cpp -----------------------------------------------------------//
3 // Copyright Beman Dawes 1994, 2006, 2008
4 // Copyright Vicente J. Botet Escriba 2009
6 // Distributed under the Boost Software License, Version 1.0.
7 // See http://www.boost.org/LICENSE_1_0.txt
9 // See http://www.boost.org/libs/chrono for documentation.
11 //--------------------------------------------------------------------------------------//
13 #include <boost/chrono/config.hpp>
14 #include <boost/chrono/process_cpu_clocks.hpp>
15 #include <boost/assert.hpp>
17 #include <sys/time.h> //for gettimeofday and timeval
18 #include <sys/times.h> //for times
25 namespace chrono_detail
28 inline long tick_factor() // multiplier to convert ticks
29 // to nanoseconds; -1 if unknown
31 static long factor = 0;
34 if ((factor = ::sysconf(_SC_CLK_TCK)) <= 0)
38 BOOST_ASSERT(factor <= 1000000000l); // doesn't handle large ticks
39 factor = 1000000000l / factor; // compute factor
49 process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_CHRONO_NOEXCEPT
53 clock_t c = ::times(&tm);
54 if (c == clock_t(-1)) // error
56 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
59 long factor = chrono_detail::tick_factor();
62 return time_point(nanoseconds(c * factor));
65 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
70 clock_t c = ::clock();
71 if (c == clock_t(-1)) // error
73 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
76 duration(c*(1000000000l/CLOCKS_PER_SEC))
81 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
82 process_real_cpu_clock::time_point process_real_cpu_clock::now(system::error_code & ec)
87 clock_t c = ::times(&tm);
88 if (c == clock_t(-1)) // error
90 if (BOOST_CHRONO_IS_THROWS(ec))
92 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock"));
95 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
100 long factor = chrono_detail::tick_factor();
103 if (!BOOST_CHRONO_IS_THROWS(ec))
107 return time_point(nanoseconds(c * factor));
110 if (BOOST_CHRONO_IS_THROWS(ec))
112 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock"));
115 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
121 clock_t c = ::clock();
122 if (c == clock_t(-1)) // error
124 if (BOOST_CHRONO_IS_THROWS(ec))
126 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_real_cpu_clock"));
129 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
134 duration(c*(1000000000l/CLOCKS_PER_SEC))
142 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
143 process_user_cpu_clock::time_point process_user_cpu_clock::now(system::error_code & ec)
146 clock_t c = ::times(&tm);
147 if (c == clock_t(-1)) // error
149 if (BOOST_CHRONO_IS_THROWS(ec))
151 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock"));
154 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
159 long factor = chrono_detail::tick_factor();
162 if (!BOOST_CHRONO_IS_THROWS(ec))
166 return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime) * factor));
169 if (BOOST_CHRONO_IS_THROWS(ec))
171 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_user_cpu_clock"));
174 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
182 process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_CHRONO_NOEXCEPT
185 clock_t c = ::times(&tm);
186 if (c == clock_t(-1)) // error
188 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
191 long factor = chrono_detail::tick_factor();
194 return time_point(nanoseconds((tm.tms_utime + tm.tms_cutime)
198 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
203 process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_CHRONO_NOEXCEPT
206 clock_t c = ::times(&tm);
207 if (c == clock_t(-1)) // error
209 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
212 long factor = chrono_detail::tick_factor();
215 return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime)
219 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
225 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
226 process_system_cpu_clock::time_point process_system_cpu_clock::now(system::error_code & ec)
229 clock_t c = ::times(&tm);
230 if (c == clock_t(-1)) // error
232 if (BOOST_CHRONO_IS_THROWS(ec))
234 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock"));
237 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
242 long factor = chrono_detail::tick_factor();
245 if (!BOOST_CHRONO_IS_THROWS(ec))
249 return time_point(nanoseconds((tm.tms_stime + tm.tms_cstime) * factor));
252 if (BOOST_CHRONO_IS_THROWS(ec))
254 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_system_cpu_clock"));
257 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
265 process_cpu_clock::time_point process_cpu_clock::now() BOOST_CHRONO_NOEXCEPT
268 clock_t c = ::times(&tm);
269 if (c == clock_t(-1)) // error
271 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
274 long factor = chrono_detail::tick_factor();
278 r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime
279 + tm.tms_cstime) * factor);
280 return time_point(duration(r));
283 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
289 #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
290 process_cpu_clock::time_point process_cpu_clock::now(system::error_code & ec)
294 clock_t c = ::times(&tm);
295 if (c == clock_t(-1)) // error
297 if (BOOST_CHRONO_IS_THROWS(ec))
299 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock"));
302 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);
307 long factor = chrono_detail::tick_factor();
311 r(c * factor, (tm.tms_utime + tm.tms_cutime) * factor, (tm.tms_stime
312 + tm.tms_cstime) * factor);
313 return time_point(duration(r));
316 if (BOOST_CHRONO_IS_THROWS(ec))
318 boost::throw_exception(system::system_error(errno, BOOST_CHRONO_SYSTEM_CATEGORY, "chrono::process_clock"));
321 ec.assign(errno, BOOST_CHRONO_SYSTEM_CATEGORY);