process_cpu_clocks.hpp 17 KB

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