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 <iosfwd> 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; process_timesboost::chrono::process_times85 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> process_timesboost::chrono::process_times92 explicit process_times( 93 Rep2 r) 94 : real(r) 95 , user(r) 96 , system(r){} 97 #endif 98 template <typename Rep2> process_timesboost::chrono::process_times99 explicit process_times( 100 process_times<Rep2> const& rhs) 101 : real(rhs.real) 102 , user(rhs.user) 103 , system(rhs.system){} process_timesboost::chrono::process_times104 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 operator repboost::chrono::process_times117 operator rep() const 118 { 119 return real; 120 } 121 #endif 122 template <typename Rep2> operator ==boost::chrono::process_times123 bool operator==(process_times<Rep2> const& rhs) { 124 return (real==rhs.real && 125 user==rhs.user && 126 system==rhs.system); 127 } 128 operator +=boost::chrono::process_times129 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 } operator -=boost::chrono::process_times137 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 } operator *=boost::chrono::process_times145 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 } operator *=boost::chrono::process_times153 process_times& operator*=(rep const& rhs) 154 { 155 real*=rhs; 156 user*=rhs; 157 system*=rhs; 158 return *this; 159 } operator /=boost::chrono::process_times160 process_times& operator/=(process_times const& rhs) 161 { 162 real/=rhs.real; 163 user/=rhs.user; 164 system/=rhs.system; 165 return *this; 166 } operator /=boost::chrono::process_times167 process_times& operator/=(rep const& rhs) 168 { 169 real/=rhs; 170 user/=rhs; 171 system/=rhs; 172 return *this; 173 } operator <boost::chrono::process_times174 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> printboost::chrono::process_times185 void print(std::basic_ostream<CharT, Traits>& os) const 186 { 187 os << "{"<< real <<";"<< user <<";"<< system << "}"; 188 } 189 190 template <class CharT, class Traits> readboost::chrono::process_times191 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 operator ==(const duration<process_times<Rep1>,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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 operator ==(const duration<process_times<Rep1>,Period1> & lhs,const duration<Rep2,Period2> & rhs)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 operator ==(const duration<Rep1,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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 operator <(const duration<process_times<Rep1>,Period1> & lhs,const duration<Rep2,Period2> & rhs)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 operator <(const duration<Rep1,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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 operator <(const duration<process_times<Rep1>,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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>& operator <<(std::basic_ostream<CharT,Traits> & os,process_times<Rep> const & rhs)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>& operator >>(std::basic_istream<CharT,Traits> & is,process_times<Rep> & rhs)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: zeroboost::chrono::duration_values348 static Res zero() 349 { 350 return Res(); 351 } BOOST_PREVENT_MACRO_SUBSTITUTIONboost::chrono::duration_values352 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 } BOOST_PREVENT_MACRO_SUBSTITUTIONboost::chrono::duration_values358 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 { nameboost::chrono::clock_string369 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 } sinceboost::chrono::clock_string378 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 { nameboost::chrono::clock_string392 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 } sinceboost::chrono::clock_string401 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 { nameboost::chrono::clock_string414 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 } sinceboost::chrono::clock_string423 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 { nameboost::chrono::clock_string436 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 } sinceboost::chrono::clock_string444 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; BOOST_PREVENT_MACRO_SUBSTITUTIONstd::numeric_limits467 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 } BOOST_PREVENT_MACRO_SUBSTITUTIONstd::numeric_limits473 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 } loweststd::numeric_limits479 static Res lowest() BOOST_NOEXCEPT_OR_NOTHROW 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 526