1// boost process_cpu_clocks.cpp -----------------------------------------------------------//
2
3// Copyright Beman Dawes 1994, 2006, 2008
4// Copyright Vicente J. Botet Escriba 2009
5
6// Distributed under the Boost Software License, Version 1.0.
7// See http://www.boost.org/LICENSE_1_0.txt
8
9// See http://www.boost.org/libs/chrono for documentation.
10
11//--------------------------------------------------------------------------------------//
12
13#include <boost/chrono/config.hpp>
14#include <boost/chrono/process_cpu_clocks.hpp>
15#include <boost/assert.hpp>
16
17#include <sys/times.h>
18#include <unistd.h>
19#include <time.h> // for clock_gettime
20
21
22namespace boost { namespace chrono {
23namespace chrono_detail
24{
25 inline nanoseconds::rep tick_factor() // multiplier to convert ticks
26 // to nanoseconds; -1 if unknown
27 {
28 long factor = 0;
29 if ( !factor )
30 {
31 if ( (factor = ::sysconf( _SC_CLK_TCK )) <= 0 )
32 factor = -1;
33 else
34 {
35 BOOST_ASSERT( factor <= 1000000000l ); // doesn't handle large ticks
36 factor = 1000000000l / factor; // compute factor
37 if ( !factor ) factor = -1;
38 }
39 }
40 return factor;
41 }
42}
43
44process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT
45{
46 tms tm;
47 clock_t c = ::times( buffer: &tm );
48 if ( c == clock_t(-1) ) // error
49 {
50 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
51 }
52 else
53 {
54 if ( chrono_detail::tick_factor() != -1 )
55 {
56 return time_point(
57 nanoseconds(c*chrono_detail::tick_factor()));
58 }
59 else
60 {
61 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
62 }
63 }
64 return time_point();
65}
66
67#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
68process_real_cpu_clock::time_point process_real_cpu_clock::now(
69 system::error_code & ec)
70{
71
72 tms tm;
73 clock_t c = ::times( buffer: &tm );
74 if ( c == clock_t(-1) ) // error
75 {
76 if (::boost::chrono::is_throws(ec))
77 {
78 boost::throw_exception(
79 e: system::system_error(
80 errno,
81 ::boost::system::system_category(),
82 "chrono::process_real_cpu_clock" ));
83 }
84 else
85 {
86 ec.assign( errno, cat: ::boost::system::system_category() );
87 return time_point();
88 }
89 }
90 else
91 {
92 if ( chrono_detail::tick_factor() != -1 )
93 {
94 if (!::boost::chrono::is_throws(ec))
95 {
96 ec.clear();
97 }
98 return time_point(
99 nanoseconds(c*chrono_detail::tick_factor()));
100 }
101 else
102 {
103 if (::boost::chrono::is_throws(ec))
104 {
105 boost::throw_exception(
106 e: system::system_error(
107 errno,
108 ::boost::system::system_category(),
109 "chrono::process_real_cpu_clock" ));
110 }
111 else
112 {
113 ec.assign( errno, cat: ::boost::system::system_category() );
114 return time_point();
115 }
116 }
117 }
118}
119#endif
120
121process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT
122{
123 tms tm;
124 clock_t c = ::times( buffer: &tm );
125 if ( c == clock_t(-1) ) // error
126 {
127 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
128 }
129 else
130 {
131 if ( chrono_detail::tick_factor() != -1 )
132 {
133 return time_point(
134 nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor()));
135 }
136 else
137 {
138 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
139 }
140 }
141 return time_point();
142}
143
144#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
145process_user_cpu_clock::time_point process_user_cpu_clock::now(
146 system::error_code & ec)
147{
148 tms tm;
149 clock_t c = ::times( buffer: &tm );
150 if ( c == clock_t(-1) ) // error
151 {
152 if (::boost::chrono::is_throws(ec))
153 {
154 boost::throw_exception(
155 e: system::system_error(
156 errno,
157 ::boost::system::system_category(),
158 "chrono::process_user_cpu_clock" ));
159 }
160 else
161 {
162 ec.assign( errno, cat: ::boost::system::system_category() );
163 return time_point();
164 }
165 }
166 else
167 {
168 if ( chrono_detail::tick_factor() != -1 )
169 {
170 if (!::boost::chrono::is_throws(ec))
171 {
172 ec.clear();
173 }
174 return time_point(
175 nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor()));
176 }
177 else
178 {
179 if (::boost::chrono::is_throws(ec))
180 {
181 boost::throw_exception(
182 e: system::system_error(
183 errno,
184 ::boost::system::system_category(),
185 "chrono::process_user_cpu_clock" ));
186 }
187 else
188 {
189 ec.assign( errno, cat: ::boost::system::system_category() );
190 return time_point();
191 }
192 }
193 }
194}
195#endif
196
197process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT
198{
199 tms tm;
200 clock_t c = ::times( buffer: &tm );
201 if ( c == clock_t(-1) ) // error
202 {
203 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
204 return time_point();
205 }
206 else
207 {
208 if ( chrono_detail::tick_factor() != -1 )
209 {
210 return time_point(
211 nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()));
212 }
213 else
214 {
215 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
216 return time_point();
217 }
218 }
219}
220
221#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
222process_system_cpu_clock::time_point process_system_cpu_clock::now(
223 system::error_code & ec)
224{
225 tms tm;
226 clock_t c = ::times( buffer: &tm );
227 if ( c == clock_t(-1) ) // error
228 {
229 if (::boost::chrono::is_throws(ec))
230 {
231 boost::throw_exception(
232 e: system::system_error(
233 errno,
234 ::boost::system::system_category(),
235 "chrono::process_system_cpu_clock" ));
236 }
237 else
238 {
239 ec.assign( errno, cat: ::boost::system::system_category() );
240 return time_point();
241 }
242 }
243 else
244 {
245 if ( chrono_detail::tick_factor() != -1 )
246 {
247 if (!::boost::chrono::is_throws(ec))
248 {
249 ec.clear();
250 }
251 return time_point(
252 nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()));
253 }
254 else
255 {
256 if (::boost::chrono::is_throws(ec))
257 {
258 boost::throw_exception(
259 e: system::system_error(
260 errno,
261 ::boost::system::system_category(),
262 "chrono::process_system_cpu_clock" ));
263 }
264 else
265 {
266 ec.assign( errno, cat: ::boost::system::system_category() );
267 return time_point();
268 }
269 }
270 }
271}
272#endif
273
274process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT
275{
276 tms tm;
277 clock_t c = ::times( buffer: &tm );
278 if ( c == clock_t(-1) ) // error
279 {
280 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
281 }
282 else
283 {
284 nanoseconds::rep factor = chrono_detail::tick_factor();
285 if ( factor != -1 )
286 {
287 time_point::rep r(
288 c*factor,
289 (tm.tms_utime + tm.tms_cutime)*factor,
290 (tm.tms_stime + tm.tms_cstime)*factor);
291 return time_point(duration(r));
292 }
293 else
294 {
295 BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
296 }
297 }
298 return time_point();
299}
300
301#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
302process_cpu_clock::time_point process_cpu_clock::now(
303 system::error_code & ec )
304{
305 tms tm;
306 clock_t c = ::times( buffer: &tm );
307 if ( c == clock_t(-1) ) // error
308 {
309 if (::boost::chrono::is_throws(ec))
310 {
311 boost::throw_exception(
312 e: system::system_error(
313 errno,
314 ::boost::system::system_category(),
315 "chrono::process_clock" ));
316 }
317 else
318 {
319 ec.assign( errno, cat: ::boost::system::system_category() );
320 return time_point();
321 }
322 }
323 else
324 {
325 if ( chrono_detail::tick_factor() != -1 )
326 {
327 time_point::rep r(
328 c*chrono_detail::tick_factor(),
329 (tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(),
330 (tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor());
331 return time_point(duration(r));
332 }
333 else
334 {
335 if (::boost::chrono::is_throws(ec))
336 {
337 boost::throw_exception(
338 e: system::system_error(
339 errno,
340 ::boost::system::system_category(),
341 "chrono::process_clock" ));
342 }
343 else
344 {
345 ec.assign( errno, cat: ::boost::system::system_category() );
346 return time_point();
347 }
348 }
349 }
350
351}
352#endif
353
354} }
355

source code of boost/libs/chrono/include/boost/chrono/detail/inlined/posix/process_cpu_clocks.hpp