process_cpu_clocks.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // boost process_cpu_clocks.cpp -----------------------------------------------------------//
  2. // Copyright Beman Dawes 1994, 2006, 2008
  3. // Copyright Vicente J. Botet Escriba 2009
  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/chrono for documentation.
  7. //--------------------------------------------------------------------------------------//
  8. #include <boost/chrono/config.hpp>
  9. #include <boost/chrono/process_cpu_clocks.hpp>
  10. #include <boost/assert.hpp>
  11. #include <sys/times.h>
  12. #include <unistd.h>
  13. #include <time.h> // for clock_gettime
  14. namespace boost { namespace chrono {
  15. namespace chrono_detail
  16. {
  17. inline nanoseconds::rep tick_factor() // multiplier to convert ticks
  18. // to nanoseconds; -1 if unknown
  19. {
  20. long factor = 0;
  21. if ( !factor )
  22. {
  23. if ( (factor = ::sysconf( _SC_CLK_TCK )) <= 0 )
  24. factor = -1;
  25. else
  26. {
  27. BOOST_ASSERT( factor <= 1000000000l ); // doesn't handle large ticks
  28. factor = 1000000000l / factor; // compute factor
  29. if ( !factor ) factor = -1;
  30. }
  31. }
  32. return factor;
  33. }
  34. }
  35. process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT
  36. {
  37. tms tm;
  38. clock_t c = ::times( &tm );
  39. if ( c == clock_t(-1) ) // error
  40. {
  41. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  42. }
  43. else
  44. {
  45. if ( chrono_detail::tick_factor() != -1 )
  46. {
  47. return time_point(
  48. nanoseconds(c*chrono_detail::tick_factor()));
  49. }
  50. else
  51. {
  52. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  53. }
  54. }
  55. return time_point();
  56. }
  57. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  58. process_real_cpu_clock::time_point process_real_cpu_clock::now(
  59. system::error_code & ec)
  60. {
  61. tms tm;
  62. clock_t c = ::times( &tm );
  63. if ( c == clock_t(-1) ) // error
  64. {
  65. if (::boost::chrono::is_throws(ec))
  66. {
  67. boost::throw_exception(
  68. system::system_error(
  69. errno,
  70. ::boost::system::system_category(),
  71. "chrono::process_real_cpu_clock" ));
  72. }
  73. else
  74. {
  75. ec.assign( errno, ::boost::system::system_category() );
  76. return time_point();
  77. }
  78. }
  79. else
  80. {
  81. if ( chrono_detail::tick_factor() != -1 )
  82. {
  83. if (!::boost::chrono::is_throws(ec))
  84. {
  85. ec.clear();
  86. }
  87. return time_point(
  88. nanoseconds(c*chrono_detail::tick_factor()));
  89. }
  90. else
  91. {
  92. if (::boost::chrono::is_throws(ec))
  93. {
  94. boost::throw_exception(
  95. system::system_error(
  96. errno,
  97. ::boost::system::system_category(),
  98. "chrono::process_real_cpu_clock" ));
  99. }
  100. else
  101. {
  102. ec.assign( errno, ::boost::system::system_category() );
  103. return time_point();
  104. }
  105. }
  106. }
  107. }
  108. #endif
  109. process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT
  110. {
  111. tms tm;
  112. clock_t c = ::times( &tm );
  113. if ( c == clock_t(-1) ) // error
  114. {
  115. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  116. }
  117. else
  118. {
  119. if ( chrono_detail::tick_factor() != -1 )
  120. {
  121. return time_point(
  122. nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor()));
  123. }
  124. else
  125. {
  126. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  127. }
  128. }
  129. return time_point();
  130. }
  131. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  132. process_user_cpu_clock::time_point process_user_cpu_clock::now(
  133. system::error_code & ec)
  134. {
  135. tms tm;
  136. clock_t c = ::times( &tm );
  137. if ( c == clock_t(-1) ) // error
  138. {
  139. if (::boost::chrono::is_throws(ec))
  140. {
  141. boost::throw_exception(
  142. system::system_error(
  143. errno,
  144. ::boost::system::system_category(),
  145. "chrono::process_user_cpu_clock" ));
  146. }
  147. else
  148. {
  149. ec.assign( errno, ::boost::system::system_category() );
  150. return time_point();
  151. }
  152. }
  153. else
  154. {
  155. if ( chrono_detail::tick_factor() != -1 )
  156. {
  157. if (!::boost::chrono::is_throws(ec))
  158. {
  159. ec.clear();
  160. }
  161. return time_point(
  162. nanoseconds((tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor()));
  163. }
  164. else
  165. {
  166. if (::boost::chrono::is_throws(ec))
  167. {
  168. boost::throw_exception(
  169. system::system_error(
  170. errno,
  171. ::boost::system::system_category(),
  172. "chrono::process_user_cpu_clock" ));
  173. }
  174. else
  175. {
  176. ec.assign( errno, ::boost::system::system_category() );
  177. return time_point();
  178. }
  179. }
  180. }
  181. }
  182. #endif
  183. process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT
  184. {
  185. tms tm;
  186. clock_t c = ::times( &tm );
  187. if ( c == clock_t(-1) ) // error
  188. {
  189. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  190. return time_point();
  191. }
  192. else
  193. {
  194. if ( chrono_detail::tick_factor() != -1 )
  195. {
  196. return time_point(
  197. nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()));
  198. }
  199. else
  200. {
  201. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  202. return time_point();
  203. }
  204. }
  205. }
  206. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  207. process_system_cpu_clock::time_point process_system_cpu_clock::now(
  208. system::error_code & ec)
  209. {
  210. tms tm;
  211. clock_t c = ::times( &tm );
  212. if ( c == clock_t(-1) ) // error
  213. {
  214. if (::boost::chrono::is_throws(ec))
  215. {
  216. boost::throw_exception(
  217. system::system_error(
  218. errno,
  219. ::boost::system::system_category(),
  220. "chrono::process_system_cpu_clock" ));
  221. }
  222. else
  223. {
  224. ec.assign( errno, ::boost::system::system_category() );
  225. return time_point();
  226. }
  227. }
  228. else
  229. {
  230. if ( chrono_detail::tick_factor() != -1 )
  231. {
  232. if (!::boost::chrono::is_throws(ec))
  233. {
  234. ec.clear();
  235. }
  236. return time_point(
  237. nanoseconds((tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor()));
  238. }
  239. else
  240. {
  241. if (::boost::chrono::is_throws(ec))
  242. {
  243. boost::throw_exception(
  244. system::system_error(
  245. errno,
  246. ::boost::system::system_category(),
  247. "chrono::process_system_cpu_clock" ));
  248. }
  249. else
  250. {
  251. ec.assign( errno, ::boost::system::system_category() );
  252. return time_point();
  253. }
  254. }
  255. }
  256. }
  257. #endif
  258. process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT
  259. {
  260. tms tm;
  261. clock_t c = ::times( &tm );
  262. if ( c == clock_t(-1) ) // error
  263. {
  264. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  265. }
  266. else
  267. {
  268. nanoseconds::rep factor = chrono_detail::tick_factor();
  269. if ( factor != -1 )
  270. {
  271. time_point::rep r(
  272. c*factor,
  273. (tm.tms_utime + tm.tms_cutime)*factor,
  274. (tm.tms_stime + tm.tms_cstime)*factor);
  275. return time_point(duration(r));
  276. }
  277. else
  278. {
  279. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  280. }
  281. }
  282. return time_point();
  283. }
  284. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  285. process_cpu_clock::time_point process_cpu_clock::now(
  286. system::error_code & ec )
  287. {
  288. tms tm;
  289. clock_t c = ::times( &tm );
  290. if ( c == clock_t(-1) ) // error
  291. {
  292. if (::boost::chrono::is_throws(ec))
  293. {
  294. boost::throw_exception(
  295. system::system_error(
  296. errno,
  297. ::boost::system::system_category(),
  298. "chrono::process_clock" ));
  299. }
  300. else
  301. {
  302. ec.assign( errno, ::boost::system::system_category() );
  303. return time_point();
  304. }
  305. }
  306. else
  307. {
  308. if ( chrono_detail::tick_factor() != -1 )
  309. {
  310. time_point::rep r(
  311. c*chrono_detail::tick_factor(),
  312. (tm.tms_utime + tm.tms_cutime)*chrono_detail::tick_factor(),
  313. (tm.tms_stime + tm.tms_cstime)*chrono_detail::tick_factor());
  314. return time_point(duration(r));
  315. }
  316. else
  317. {
  318. if (::boost::chrono::is_throws(ec))
  319. {
  320. boost::throw_exception(
  321. system::system_error(
  322. errno,
  323. ::boost::system::system_category(),
  324. "chrono::process_clock" ));
  325. }
  326. else
  327. {
  328. ec.assign( errno, ::boost::system::system_category() );
  329. return time_point();
  330. }
  331. }
  332. }
  333. }
  334. #endif
  335. } }