process_cpu_clocks.hpp 9.9 KB

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