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; 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<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 operator ==(const duration<process_times<Rep1>,Period1> & lhs,const duration<Rep2,Period2> & rhs)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 operator ==(const duration<Rep1,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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 operator <(const duration<process_times<Rep1>,Period1> & lhs,const duration<Rep2,Period2> & rhs)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 operator <(const duration<Rep1,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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 operator <(const duration<process_times<Rep1>,Period1> & lhs,const duration<process_times<Rep2>,Period2> & rhs)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>& operator <<(std::basic_ostream<CharT,Traits> & os,process_times<Rep> const & rhs)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>& operator >>(std::basic_istream<CharT,Traits> & is,process_times<Rep> & rhs)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: zeroboost::chrono::duration_values345 static Res zero() 346 { 347 return Res(); 348 } BOOST_PREVENT_MACRO_SUBSTITUTIONboost::chrono::duration_values349 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 } BOOST_PREVENT_MACRO_SUBSTITUTIONboost::chrono::duration_values355 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 { nameboost::chrono::clock_string366 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 } sinceboost::chrono::clock_string375 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 { nameboost::chrono::clock_string389 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 } sinceboost::chrono::clock_string398 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 { nameboost::chrono::clock_string411 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 } sinceboost::chrono::clock_string420 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 { nameboost::chrono::clock_string433 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 } sinceboost::chrono::clock_string441 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 455 namespace 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; BOOST_PREVENT_MACRO_SUBSTITUTIONstd::numeric_limits464 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 } BOOST_PREVENT_MACRO_SUBSTITUTIONstd::numeric_limits470 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 } loweststd::numeric_limits476 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