process_cpu_clocks.hpp 17 KB

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