1// boost/chrono/process_cpu_clocks.hpp -----------------------------------------------------------//
2
3// Copyright 2009-2011 Vicente J. Botet Escriba
4// Copyright (c) Microsoft Corporation 2014
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/system for documentation.
10
11#ifndef BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP
12#define BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP
13
14#include <boost/chrono/config.hpp>
15
16
17#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
18
19#include <boost/chrono/duration.hpp>
20#include <boost/chrono/time_point.hpp>
21#include <boost/operators.hpp>
22#include <boost/chrono/detail/system.hpp>
23#include <iostream>
24#include <boost/type_traits/common_type.hpp>
25#include <boost/chrono/clock_string.hpp>
26
27#ifndef BOOST_CHRONO_HEADER_ONLY
28#include <boost/config/abi_prefix.hpp> // must be the last #include
29#endif
30
31namespace boost { namespace chrono {
32
33 class BOOST_CHRONO_DECL process_real_cpu_clock {
34 public:
35 typedef nanoseconds duration;
36 typedef duration::rep rep;
37 typedef duration::period period;
38 typedef chrono::time_point<process_real_cpu_clock> time_point;
39 BOOST_STATIC_CONSTEXPR bool is_steady = true;
40
41 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
42#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
43 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec );
44#endif
45 };
46
47#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
48 class BOOST_CHRONO_DECL process_user_cpu_clock {
49 public:
50 typedef nanoseconds duration;
51 typedef duration::rep rep;
52 typedef duration::period period;
53 typedef chrono::time_point<process_user_cpu_clock> time_point;
54 BOOST_STATIC_CONSTEXPR bool is_steady = true;
55
56 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
57#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
58 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec );
59#endif
60 };
61
62 class BOOST_CHRONO_DECL process_system_cpu_clock {
63 public:
64 typedef nanoseconds duration;
65 typedef duration::rep rep;
66 typedef duration::period period;
67 typedef chrono::time_point<process_system_cpu_clock> time_point;
68 BOOST_STATIC_CONSTEXPR bool is_steady = true;
69
70 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
71#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
72 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec );
73#endif
74 };
75#endif
76
77 template <typename Rep>
78 struct process_times
79 : arithmetic<process_times<Rep>,
80 multiplicative<process_times<Rep>, Rep,
81 less_than_comparable<process_times<Rep> > > >
82 {
83 //typedef process_real_cpu_clock::rep rep;
84 typedef Rep rep;
85 process_times()
86 : real(0)
87 , user(0)
88 , system(0){}
89
90#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
91 template <typename Rep2>
92 explicit process_times(
93 Rep2 r)
94 : real(r)
95 , user(r)
96 , system(r){}
97#endif
98 template <typename Rep2>
99 explicit process_times(
100 process_times<Rep2> const& rhs)
101 : real(rhs.real)
102 , user(rhs.user)
103 , system(rhs.system){}
104 process_times(
105 rep r,
106 rep u,
107 rep s)
108 : real(r)
109 , user(u)
110 , system(s){}
111
112 rep real; // real (i.e wall clock) time
113 rep user; // user cpu time
114 rep system; // system cpu time
115
116#if ! defined BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0
117 operator rep() const
118 {
119 return real;
120 }
121#endif
122 template <typename Rep2>
123 bool operator==(process_times<Rep2> const& rhs) {
124 return (real==rhs.real &&
125 user==rhs.user &&
126 system==rhs.system);
127 }
128
129 process_times& operator+=(
130 process_times const& rhs)
131 {
132 real+=rhs.real;
133 user+=rhs.user;
134 system+=rhs.system;
135 return *this;
136 }
137 process_times& operator-=(
138 process_times const& rhs)
139 {
140 real-=rhs.real;
141 user-=rhs.user;
142 system-=rhs.system;
143 return *this;
144 }
145 process_times& operator*=(
146 process_times const& rhs)
147 {
148 real*=rhs.real;
149 user*=rhs.user;
150 system*=rhs.system;
151 return *this;
152 }
153 process_times& operator*=(rep const& rhs)
154 {
155 real*=rhs;
156 user*=rhs;
157 system*=rhs;
158 return *this;
159 }
160 process_times& operator/=(process_times const& rhs)
161 {
162 real/=rhs.real;
163 user/=rhs.user;
164 system/=rhs.system;
165 return *this;
166 }
167 process_times& operator/=(rep const& rhs)
168 {
169 real/=rhs;
170 user/=rhs;
171 system/=rhs;
172 return *this;
173 }
174 bool operator<(process_times const & rhs) const
175 {
176 if (real < rhs.real) return true;
177 if (real > rhs.real) return false;
178 if (user < rhs.user) return true;
179 if (user > rhs.user) return false;
180 if (system < rhs.system) return true;
181 else return false;
182 }
183
184 template <class CharT, class Traits>
185 void print(std::basic_ostream<CharT, Traits>& os) const
186 {
187 os << "{"<< real <<";"<< user <<";"<< system << "}";
188 }
189
190 template <class CharT, class Traits>
191 void read(std::basic_istream<CharT, Traits>& is)
192 {
193 typedef std::istreambuf_iterator<CharT, Traits> in_iterator;
194 in_iterator i(is);
195 in_iterator e;
196 if (i == e || *i != '{') // mandatory '{'
197 {
198 is.setstate(is.failbit | is.eofbit);
199 return;
200 }
201 CharT x,y,z;
202 is >> real >> x >> user >> y >> system >> z;
203 if (!is.good() || (x != ';')|| (y != ';')|| (z != '}'))
204 {
205 is.setstate(is.failbit);
206 }
207 }
208 };
209}
210template <class Rep1, class Rep2>
211struct common_type<
212 chrono::process_times<Rep1>,
213 chrono::process_times<Rep2>
214>
215{
216 typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type;
217};
218
219template <class Rep1, class Rep2>
220struct common_type<
221 chrono::process_times<Rep1>,
222 Rep2
223>
224{
225 typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type;
226};
227
228template <class Rep1, class Rep2>
229struct common_type<
230 Rep1,
231 chrono::process_times<Rep2>
232>
233{
234 typedef chrono::process_times<typename common_type<Rep1, Rep2>::type> type;
235};
236
237
238namespace chrono
239{
240 template <class Rep1, class Period1, class Rep2, class Period2>
241 inline BOOST_CONSTEXPR
242 bool
243 operator==(const duration<process_times<Rep1>, Period1>& lhs,
244 const duration<process_times<Rep2>, Period2>& rhs)
245 {
246 return boost::chrono::detail::duration_eq<
247 duration<process_times<Rep1>, Period1>, duration<process_times<Rep2>, Period2> >()(lhs, rhs);
248 }
249
250 template <class Rep1, class Period1, class Rep2, class Period2>
251 inline BOOST_CONSTEXPR
252 bool
253 operator==(const duration<process_times<Rep1>, Period1>& lhs,
254 const duration<Rep2, Period2>& rhs)
255 {
256 return boost::chrono::detail::duration_eq<
257 duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs);
258 }
259
260 template <class Rep1, class Period1, class Rep2, class Period2>
261 inline BOOST_CONSTEXPR
262 bool
263 operator==(const duration<Rep1, Period1>& lhs,
264 const duration<process_times<Rep2>, Period2>& rhs)
265 {
266 return rhs == lhs;
267 }
268
269
270 // Duration <
271
272 template <class Rep1, class Period1, class Rep2, class Period2>
273 inline BOOST_CONSTEXPR
274 bool
275 operator< (const duration<process_times<Rep1>, Period1>& lhs,
276 const duration<Rep2, Period2>& rhs)
277 {
278 return boost::chrono::detail::duration_lt<
279 duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs);
280 }
281
282 template <class Rep1, class Period1, class Rep2, class Period2>
283 inline BOOST_CONSTEXPR
284 bool
285 operator< (const duration<Rep1, Period1>& lhs,
286 const duration<process_times<Rep2>, Period2>& rhs)
287 {
288 return rhs < lhs;
289 }
290
291 template <class Rep1, class Period1, class Rep2, class Period2>
292 inline BOOST_CONSTEXPR
293 bool
294 operator< (const duration<process_times<Rep1>, Period1>& lhs,
295 const duration<process_times<Rep2>, Period2>& rhs)
296 {
297 return boost::chrono::detail::duration_lt<
298 duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, rhs);
299 }
300
301
302 typedef process_times<nanoseconds::rep> process_cpu_clock_times;
303#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
304 class BOOST_CHRONO_DECL process_cpu_clock
305 {
306 public:
307
308 typedef process_cpu_clock_times times;
309 typedef boost::chrono::duration<times, nano> duration;
310 typedef duration::rep rep;
311 typedef duration::period period;
312 typedef chrono::time_point<process_cpu_clock> time_point;
313 BOOST_STATIC_CONSTEXPR bool is_steady = true;
314
315 static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT;
316#if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
317 static BOOST_CHRONO_INLINE time_point now(system::error_code & ec );
318#endif
319 };
320#endif
321
322 template <class CharT, class Traits, typename Rep>
323 std::basic_ostream<CharT, Traits>&
324 operator<<(std::basic_ostream<CharT, Traits>& os,
325 process_times<Rep> const& rhs)
326 {
327 rhs.print(os);
328 return os;
329 }
330
331 template <class CharT, class Traits, typename Rep>
332 std::basic_istream<CharT, Traits>&
333 operator>>(std::basic_istream<CharT, Traits>& is,
334 process_times<Rep>& rhs)
335 {
336 rhs.read(is);
337 return is;
338 }
339
340 template <typename Rep>
341 struct duration_values<process_times<Rep> >
342 {
343 typedef process_times<Rep> Res;
344 public:
345 static Res zero()
346 {
347 return Res();
348 }
349 static Res max BOOST_PREVENT_MACRO_SUBSTITUTION ()
350 {
351 return Res((std::numeric_limits<Rep>::max)(),
352 (std::numeric_limits<Rep>::max)(),
353 (std::numeric_limits<Rep>::max)());
354 }
355 static Res min BOOST_PREVENT_MACRO_SUBSTITUTION ()
356 {
357 return Res((std::numeric_limits<Rep>::min)(),
358 (std::numeric_limits<Rep>::min)(),
359 (std::numeric_limits<Rep>::min)());
360 }
361 };
362
363 template<class CharT>
364 struct clock_string<process_real_cpu_clock, CharT>
365 {
366 static std::basic_string<CharT> name()
367 {
368 static const CharT
369 u[] =
370 { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'r', 'e', 'a', 'l', '_', 'c', 'l', 'o', 'c', 'k' };
371 static const std::basic_string<CharT> str(u, u + sizeof(u)
372 / sizeof(u[0]));
373 return str;
374 }
375 static std::basic_string<CharT> since()
376 {
377 const CharT
378 u[] =
379 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' };
380 const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0]));
381 return str;
382 }
383 };
384
385#if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP
386 template<class CharT>
387 struct clock_string<process_user_cpu_clock, CharT>
388 {
389 static std::basic_string<CharT> name()
390 {
391 static const CharT
392 u[] =
393 { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'u', 's', 'e', 'r', '_', 'c', 'l', 'o', 'c', 'k' };
394 static const std::basic_string<CharT> str(u, u + sizeof(u)
395 / sizeof(u[0]));
396 return str;
397 }
398 static std::basic_string<CharT> since()
399 {
400 const CharT
401 u[] =
402 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' };
403 const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0]));
404 return str;
405 }
406 };
407
408 template<class CharT>
409 struct clock_string<process_system_cpu_clock, CharT>
410 {
411 static std::basic_string<CharT> name()
412 {
413 static const CharT
414 u[] =
415 { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 's', 'y', 's', 't', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' };
416 static const std::basic_string<CharT> str(u, u + sizeof(u)
417 / sizeof(u[0]));
418 return str;
419 }
420 static std::basic_string<CharT> since()
421 {
422 const CharT
423 u[] =
424 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' };
425 const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0]));
426 return str;
427 }
428 };
429
430 template<class CharT>
431 struct clock_string<process_cpu_clock, CharT>
432 {
433 static std::basic_string<CharT> name()
434 {
435 static const CharT u[] =
436 { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'c', 'l', 'o', 'c', 'k' };
437 static const std::basic_string<CharT> str(u, u + sizeof(u)
438 / sizeof(u[0]));
439 return str;
440 }
441 static std::basic_string<CharT> since()
442 {
443 const CharT
444 u[] =
445 { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' };
446 const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0]));
447 return str;
448 }
449 };
450#endif
451
452} // namespace chrono
453} // namespace boost
454
455namespace std {
456
457 template <typename Rep>
458 struct numeric_limits<boost::chrono::process_times<Rep> >
459 {
460 typedef boost::chrono::process_times<Rep> Res;
461
462 public:
463 static const bool is_specialized = true;
464 static Res min BOOST_PREVENT_MACRO_SUBSTITUTION ()
465 {
466 return Res((std::numeric_limits<Rep>::min)(),
467 (std::numeric_limits<Rep>::min)(),
468 (std::numeric_limits<Rep>::min)());
469 }
470 static Res max BOOST_PREVENT_MACRO_SUBSTITUTION ()
471 {
472 return Res((std::numeric_limits<Rep>::max)(),
473 (std::numeric_limits<Rep>::max)(),
474 (std::numeric_limits<Rep>::max)());
475 }
476 static Res lowest() throw()
477 {
478 return (min)();
479 }
480 static const int digits = std::numeric_limits<Rep>::digits+
481 std::numeric_limits<Rep>::digits+
482 std::numeric_limits<Rep>::digits;
483 static const int digits10 = std::numeric_limits<Rep>::digits10+
484 std::numeric_limits<Rep>::digits10+
485 std::numeric_limits<Rep>::digits10;
486 static const bool is_signed = Rep::is_signed;
487 static const bool is_integer = Rep::is_integer;
488 static const bool is_exact = Rep::is_exact;
489 static const int radix = 0;
490 //~ static Res epsilon() throw() { return 0; }
491 //~ static Res round_error() throw() { return 0; }
492 //~ static const int min_exponent = 0;
493 //~ static const int min_exponent10 = 0;
494 //~ static const int max_exponent = 0;
495 //~ static const int max_exponent10 = 0;
496 //~ static const bool has_infinity = false;
497 //~ static const bool has_quiet_NaN = false;
498 //~ static const bool has_signaling_NaN = false;
499 //~ static const float_denorm_style has_denorm = denorm_absent;
500 //~ static const bool has_denorm_loss = false;
501 //~ static Res infinity() throw() { return 0; }
502 //~ static Res quiet_NaN() throw() { return 0; }
503 //~ static Res signaling_NaN() throw() { return 0; }
504 //~ static Res denorm_min() throw() { return 0; }
505 //~ static const bool is_iec559 = false;
506 //~ static const bool is_bounded = true;
507 //~ static const bool is_modulo = false;
508 //~ static const bool traps = false;
509 //~ static const bool tinyness_before = false;
510 //~ static const float_round_style round_style = round_toward_zero;
511
512 };
513}
514
515#ifndef BOOST_CHRONO_HEADER_ONLY
516#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
517#else
518#include <boost/chrono/detail/inlined/process_cpu_clocks.hpp>
519#endif
520#endif
521
522#endif // BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP
523

source code of boost/boost/chrono/process_cpu_clocks.hpp