]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
31 | namespace 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 | } | |
210 | template <class Rep1, class Rep2> | |
211 | struct 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 | ||
219 | template <class Rep1, class Rep2> | |
220 | struct 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 | ||
228 | template <class Rep1, class Rep2> | |
229 | struct 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 | ||
238 | namespace 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<Rep1, Period1>, duration<Rep2, Period2> | |
248 | >()(duration<Rep1, Period1>(lhs.count().real), duration<Rep2, Period2>(rhs.count().real)); | |
249 | } | |
250 | ||
251 | template <class Rep1, class Period1, class Rep2, class Period2> | |
252 | inline BOOST_CONSTEXPR | |
253 | bool | |
254 | operator==(const duration<process_times<Rep1>, Period1>& lhs, | |
255 | const duration<Rep2, Period2>& rhs) | |
256 | { | |
257 | return boost::chrono::detail::duration_eq< | |
258 | duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs); | |
259 | } | |
260 | ||
261 | template <class Rep1, class Period1, class Rep2, class Period2> | |
262 | inline BOOST_CONSTEXPR | |
263 | bool | |
264 | operator==(const duration<Rep1, Period1>& lhs, | |
265 | const duration<process_times<Rep2>, Period2>& rhs) | |
266 | { | |
267 | return rhs == lhs; | |
268 | } | |
269 | ||
270 | ||
271 | // Duration < | |
272 | ||
273 | template <class Rep1, class Period1, class Rep2, class Period2> | |
274 | inline BOOST_CONSTEXPR | |
275 | bool | |
276 | operator< (const duration<process_times<Rep1>, Period1>& lhs, | |
277 | const duration<Rep2, Period2>& rhs) | |
278 | { | |
279 | return boost::chrono::detail::duration_lt< | |
280 | duration<Rep1, Period1>, duration<Rep2, Period2> >()(duration<Rep1, Period1>(lhs.count().real), rhs); | |
281 | } | |
282 | ||
283 | template <class Rep1, class Period1, class Rep2, class Period2> | |
284 | inline BOOST_CONSTEXPR | |
285 | bool | |
286 | operator< (const duration<Rep1, Period1>& lhs, | |
287 | const duration<process_times<Rep2>, Period2>& rhs) | |
288 | { | |
289 | return boost::chrono::detail::duration_lt< | |
290 | duration<Rep1, Period1>, duration<Rep2, Period2> >()(lhs, duration<Rep2, Period2>(rhs.count().real)); | |
291 | } | |
292 | ||
293 | template <class Rep1, class Period1, class Rep2, class Period2> | |
294 | inline BOOST_CONSTEXPR | |
295 | bool | |
296 | operator< (const duration<process_times<Rep1>, Period1>& lhs, | |
297 | const duration<process_times<Rep2>, Period2>& rhs) | |
298 | { | |
299 | return boost::chrono::detail::duration_lt< | |
300 | duration<Rep1, Period1>, duration<Rep2, Period2> | |
301 | >()(duration<Rep1, Period1>(lhs.count().real), duration<Rep2, Period2>(rhs.count().real)); | |
302 | } | |
303 | ||
304 | ||
305 | typedef process_times<nanoseconds::rep> process_cpu_clock_times; | |
306 | #if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP | |
307 | class BOOST_CHRONO_DECL process_cpu_clock | |
308 | { | |
309 | public: | |
310 | ||
311 | typedef process_cpu_clock_times times; | |
312 | typedef boost::chrono::duration<times, nano> duration; | |
313 | typedef duration::rep rep; | |
314 | typedef duration::period period; | |
315 | typedef chrono::time_point<process_cpu_clock> time_point; | |
316 | BOOST_STATIC_CONSTEXPR bool is_steady = true; | |
317 | ||
318 | static BOOST_CHRONO_INLINE time_point now() BOOST_NOEXCEPT; | |
319 | #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING | |
320 | static BOOST_CHRONO_INLINE time_point now(system::error_code & ec ); | |
321 | #endif | |
322 | }; | |
323 | #endif | |
324 | ||
325 | template <class CharT, class Traits, typename Rep> | |
326 | std::basic_ostream<CharT, Traits>& | |
327 | operator<<(std::basic_ostream<CharT, Traits>& os, | |
328 | process_times<Rep> const& rhs) | |
329 | { | |
330 | rhs.print(os); | |
331 | return os; | |
332 | } | |
333 | ||
334 | template <class CharT, class Traits, typename Rep> | |
335 | std::basic_istream<CharT, Traits>& | |
336 | operator>>(std::basic_istream<CharT, Traits>& is, | |
337 | process_times<Rep>& rhs) | |
338 | { | |
339 | rhs.read(is); | |
340 | return is; | |
341 | } | |
342 | ||
343 | template <typename Rep> | |
344 | struct duration_values<process_times<Rep> > | |
345 | { | |
346 | typedef process_times<Rep> Res; | |
347 | public: | |
348 | static Res zero() | |
349 | { | |
350 | return Res(); | |
351 | } | |
352 | static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () | |
353 | { | |
354 | return Res((std::numeric_limits<Rep>::max)(), | |
355 | (std::numeric_limits<Rep>::max)(), | |
356 | (std::numeric_limits<Rep>::max)()); | |
357 | } | |
358 | static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () | |
359 | { | |
360 | return Res((std::numeric_limits<Rep>::min)(), | |
361 | (std::numeric_limits<Rep>::min)(), | |
362 | (std::numeric_limits<Rep>::min)()); | |
363 | } | |
364 | }; | |
365 | ||
366 | template<class CharT> | |
367 | struct clock_string<process_real_cpu_clock, CharT> | |
368 | { | |
369 | static std::basic_string<CharT> name() | |
370 | { | |
371 | static const CharT | |
372 | u[] = | |
373 | { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'r', 'e', 'a', 'l', '_', 'c', 'l', 'o', 'c', 'k' }; | |
374 | static const std::basic_string<CharT> str(u, u + sizeof(u) | |
375 | / sizeof(u[0])); | |
376 | return str; | |
377 | } | |
378 | static std::basic_string<CharT> since() | |
379 | { | |
380 | const CharT | |
381 | u[] = | |
382 | { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; | |
383 | const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); | |
384 | return str; | |
385 | } | |
386 | }; | |
387 | ||
388 | #if ! BOOST_OS_WINDOWS || BOOST_PLAT_WINDOWS_DESKTOP | |
389 | template<class CharT> | |
390 | struct clock_string<process_user_cpu_clock, CharT> | |
391 | { | |
392 | static std::basic_string<CharT> name() | |
393 | { | |
394 | static const CharT | |
395 | u[] = | |
396 | { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'u', 's', 'e', 'r', '_', 'c', 'l', 'o', 'c', 'k' }; | |
397 | static const std::basic_string<CharT> str(u, u + sizeof(u) | |
398 | / sizeof(u[0])); | |
399 | return str; | |
400 | } | |
401 | static std::basic_string<CharT> since() | |
402 | { | |
403 | const CharT | |
404 | u[] = | |
405 | { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; | |
406 | const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); | |
407 | return str; | |
408 | } | |
409 | }; | |
410 | ||
411 | template<class CharT> | |
412 | struct clock_string<process_system_cpu_clock, CharT> | |
413 | { | |
414 | static std::basic_string<CharT> name() | |
415 | { | |
416 | static const CharT | |
417 | u[] = | |
418 | { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 's', 'y', 's', 't', 'e', 'm', '_', 'c', 'l', 'o', 'c', 'k' }; | |
419 | static const std::basic_string<CharT> str(u, u + sizeof(u) | |
420 | / sizeof(u[0])); | |
421 | return str; | |
422 | } | |
423 | static std::basic_string<CharT> since() | |
424 | { | |
425 | const CharT | |
426 | u[] = | |
427 | { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; | |
428 | const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); | |
429 | return str; | |
430 | } | |
431 | }; | |
432 | ||
433 | template<class CharT> | |
434 | struct clock_string<process_cpu_clock, CharT> | |
435 | { | |
436 | static std::basic_string<CharT> name() | |
437 | { | |
438 | static const CharT u[] = | |
439 | { 'p', 'r', 'o', 'c', 'e', 's', 's', '_', 'c', 'l', 'o', 'c', 'k' }; | |
440 | static const std::basic_string<CharT> str(u, u + sizeof(u) | |
441 | / sizeof(u[0])); | |
442 | return str; | |
443 | } | |
444 | static std::basic_string<CharT> since() | |
445 | { | |
446 | const CharT | |
447 | u[] = | |
448 | { ' ', 's', 'i', 'n', 'c', 'e', ' ', 'p', 'r', 'o', 'c', 'e', 's', 's', ' ', 's', 't', 'a', 'r', 't', '-', 'u', 'p' }; | |
449 | const std::basic_string<CharT> str(u, u + sizeof(u) / sizeof(u[0])); | |
450 | return str; | |
451 | } | |
452 | }; | |
453 | #endif | |
454 | ||
455 | } // namespace chrono | |
456 | } // namespace boost | |
457 | ||
458 | namespace std { | |
459 | ||
460 | template <typename Rep> | |
461 | struct numeric_limits<boost::chrono::process_times<Rep> > | |
462 | { | |
463 | typedef boost::chrono::process_times<Rep> Res; | |
464 | ||
465 | public: | |
466 | static const bool is_specialized = true; | |
467 | static Res min BOOST_PREVENT_MACRO_SUBSTITUTION () | |
468 | { | |
469 | return Res((std::numeric_limits<Rep>::min)(), | |
470 | (std::numeric_limits<Rep>::min)(), | |
471 | (std::numeric_limits<Rep>::min)()); | |
472 | } | |
473 | static Res max BOOST_PREVENT_MACRO_SUBSTITUTION () | |
474 | { | |
475 | return Res((std::numeric_limits<Rep>::max)(), | |
476 | (std::numeric_limits<Rep>::max)(), | |
477 | (std::numeric_limits<Rep>::max)()); | |
478 | } | |
479 | static Res lowest() throw() | |
480 | { | |
481 | return (min)(); | |
482 | } | |
483 | static const int digits = std::numeric_limits<Rep>::digits+ | |
484 | std::numeric_limits<Rep>::digits+ | |
485 | std::numeric_limits<Rep>::digits; | |
486 | static const int digits10 = std::numeric_limits<Rep>::digits10+ | |
487 | std::numeric_limits<Rep>::digits10+ | |
488 | std::numeric_limits<Rep>::digits10; | |
489 | static const bool is_signed = Rep::is_signed; | |
490 | static const bool is_integer = Rep::is_integer; | |
491 | static const bool is_exact = Rep::is_exact; | |
492 | static const int radix = 0; | |
493 | //~ static Res epsilon() throw() { return 0; } | |
494 | //~ static Res round_error() throw() { return 0; } | |
495 | //~ static const int min_exponent = 0; | |
496 | //~ static const int min_exponent10 = 0; | |
497 | //~ static const int max_exponent = 0; | |
498 | //~ static const int max_exponent10 = 0; | |
499 | //~ static const bool has_infinity = false; | |
500 | //~ static const bool has_quiet_NaN = false; | |
501 | //~ static const bool has_signaling_NaN = false; | |
502 | //~ static const float_denorm_style has_denorm = denorm_absent; | |
503 | //~ static const bool has_denorm_loss = false; | |
504 | //~ static Res infinity() throw() { return 0; } | |
505 | //~ static Res quiet_NaN() throw() { return 0; } | |
506 | //~ static Res signaling_NaN() throw() { return 0; } | |
507 | //~ static Res denorm_min() throw() { return 0; } | |
508 | //~ static const bool is_iec559 = false; | |
509 | //~ static const bool is_bounded = true; | |
510 | //~ static const bool is_modulo = false; | |
511 | //~ static const bool traps = false; | |
512 | //~ static const bool tinyness_before = false; | |
513 | //~ static const float_round_style round_style = round_toward_zero; | |
514 | ||
515 | }; | |
516 | } | |
517 | ||
518 | #ifndef BOOST_CHRONO_HEADER_ONLY | |
519 | #include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas | |
520 | #else | |
521 | #include <boost/chrono/detail/inlined/process_cpu_clocks.hpp> | |
522 | #endif | |
523 | #endif | |
524 | ||
525 | #endif // BOOST_CHRONO_PROCESS_CPU_CLOCKS_HPP |