process_cpu_clocks.hpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // boost process_timer.cpp -----------------------------------------------------------//
  2. // Copyright Beman Dawes 1994, 2006, 2008
  3. // Copyright 2009-2010 Vicente J. Botet Escriba
  4. // Copyright (c) Microsoft Corporation 2014
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // See http://www.boost.org/LICENSE_1_0.txt
  7. // See http://www.boost.org/libs/chrono for documentation.
  8. //--------------------------------------------------------------------------------------//
  9. #ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP
  10. #define BOOST_CHRONO_DETAIL_INLINED_WIN_PROCESS_CLOCK_HPP
  11. #include <boost/chrono/config.hpp>
  12. #include <boost/chrono/process_cpu_clocks.hpp>
  13. #include <cassert>
  14. #include <time.h>
  15. #include <boost/assert.hpp>
  16. #include <boost/detail/winapi/get_last_error.hpp>
  17. #include <boost/detail/winapi/get_current_process.hpp>
  18. #if BOOST_PLAT_WINDOWS_DESKTOP
  19. #include <boost/detail/winapi/get_process_times.hpp>
  20. #endif
  21. namespace boost
  22. {
  23. namespace chrono
  24. {
  25. process_real_cpu_clock::time_point process_real_cpu_clock::now() BOOST_NOEXCEPT
  26. {
  27. clock_t c = ::clock();
  28. if ( c == clock_t(-1) ) // error
  29. {
  30. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  31. }
  32. typedef ratio_divide<giga, ratio<CLOCKS_PER_SEC> >::type R;
  33. return time_point(
  34. duration(static_cast<rep>(c)*R::num/R::den)
  35. );
  36. }
  37. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  38. process_real_cpu_clock::time_point process_real_cpu_clock::now(
  39. system::error_code & ec)
  40. {
  41. clock_t c = ::clock();
  42. if ( c == clock_t(-1) ) // error
  43. {
  44. boost::throw_exception(
  45. system::system_error(
  46. errno,
  47. ::boost::system::system_category(),
  48. "chrono::process_real_cpu_clock" ));
  49. }
  50. if (!::boost::chrono::is_throws(ec))
  51. {
  52. ec.clear();
  53. }
  54. typedef ratio_divide<giga, ratio<CLOCKS_PER_SEC> >::type R;
  55. return time_point(
  56. duration(static_cast<rep>(c)*R::num/R::den)
  57. );
  58. }
  59. #endif
  60. #if BOOST_PLAT_WINDOWS_DESKTOP
  61. process_user_cpu_clock::time_point process_user_cpu_clock::now() BOOST_NOEXCEPT
  62. {
  63. // note that Windows uses 100 nanosecond ticks for FILETIME
  64. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  65. if ( boost::detail::winapi::GetProcessTimes(
  66. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  67. &system_time, &user_time ) )
  68. {
  69. return time_point(duration(
  70. ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32)
  71. | user_time.dwLowDateTime) * 100
  72. ));
  73. }
  74. else
  75. {
  76. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  77. return time_point();
  78. }
  79. }
  80. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  81. process_user_cpu_clock::time_point process_user_cpu_clock::now(
  82. system::error_code & ec)
  83. {
  84. // note that Windows uses 100 nanosecond ticks for FILETIME
  85. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  86. if ( boost::detail::winapi::GetProcessTimes(
  87. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  88. &system_time, &user_time ) )
  89. {
  90. if (!::boost::chrono::is_throws(ec))
  91. {
  92. ec.clear();
  93. }
  94. return time_point(duration(
  95. ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32)
  96. | user_time.dwLowDateTime) * 100
  97. ));
  98. }
  99. else
  100. {
  101. boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
  102. if (::boost::chrono::is_throws(ec))
  103. {
  104. boost::throw_exception(
  105. system::system_error(
  106. cause,
  107. ::boost::system::system_category(),
  108. "chrono::process_user_cpu_clock" ));
  109. }
  110. else
  111. {
  112. ec.assign( cause, ::boost::system::system_category() );
  113. return time_point();
  114. }
  115. }
  116. }
  117. #endif
  118. process_system_cpu_clock::time_point process_system_cpu_clock::now() BOOST_NOEXCEPT
  119. {
  120. // note that Windows uses 100 nanosecond ticks for FILETIME
  121. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  122. if ( boost::detail::winapi::GetProcessTimes(
  123. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  124. &system_time, &user_time ) )
  125. {
  126. return time_point(duration(
  127. ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32)
  128. | system_time.dwLowDateTime) * 100
  129. ));
  130. }
  131. else
  132. {
  133. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  134. return time_point();
  135. }
  136. }
  137. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  138. process_system_cpu_clock::time_point process_system_cpu_clock::now(
  139. system::error_code & ec)
  140. {
  141. // note that Windows uses 100 nanosecond ticks for FILETIME
  142. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  143. if ( boost::detail::winapi::GetProcessTimes(
  144. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  145. &system_time, &user_time ) )
  146. {
  147. if (!::boost::chrono::is_throws(ec))
  148. {
  149. ec.clear();
  150. }
  151. return time_point(duration(
  152. ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32)
  153. | system_time.dwLowDateTime) * 100
  154. ));
  155. }
  156. else
  157. {
  158. boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
  159. if (::boost::chrono::is_throws(ec))
  160. {
  161. boost::throw_exception(
  162. system::system_error(
  163. cause,
  164. ::boost::system::system_category(),
  165. "chrono::process_system_cpu_clock" ));
  166. }
  167. else
  168. {
  169. ec.assign( cause, ::boost::system::system_category() );
  170. return time_point();
  171. }
  172. }
  173. }
  174. #endif
  175. process_cpu_clock::time_point process_cpu_clock::now() BOOST_NOEXCEPT
  176. {
  177. // note that Windows uses 100 nanosecond ticks for FILETIME
  178. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  179. if ( boost::detail::winapi::GetProcessTimes(
  180. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  181. &system_time, &user_time ) )
  182. {
  183. time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count()
  184. ,
  185. ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32)
  186. | user_time.dwLowDateTime
  187. ) * 100,
  188. ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32)
  189. | system_time.dwLowDateTime
  190. ) * 100
  191. );
  192. return time_point(duration(r));
  193. }
  194. else
  195. {
  196. BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
  197. return time_point();
  198. }
  199. }
  200. #if !defined BOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING
  201. process_cpu_clock::time_point process_cpu_clock::now(
  202. system::error_code & ec )
  203. {
  204. // note that Windows uses 100 nanosecond ticks for FILETIME
  205. boost::detail::winapi::FILETIME_ creation, exit, user_time, system_time;
  206. if ( boost::detail::winapi::GetProcessTimes(
  207. boost::detail::winapi::GetCurrentProcess(), &creation, &exit,
  208. &system_time, &user_time ) )
  209. {
  210. if (!::boost::chrono::is_throws(ec))
  211. {
  212. ec.clear();
  213. }
  214. time_point::rep r(process_real_cpu_clock::now().time_since_epoch().count()
  215. ,
  216. ((static_cast<process_user_cpu_clock::rep>(user_time.dwHighDateTime) << 32)
  217. | user_time.dwLowDateTime
  218. ) * 100,
  219. ((static_cast<process_system_cpu_clock::rep>(system_time.dwHighDateTime) << 32)
  220. | system_time.dwLowDateTime
  221. ) * 100
  222. );
  223. return time_point(duration(r));
  224. }
  225. else
  226. {
  227. boost::detail::winapi::DWORD_ cause = boost::detail::winapi::GetLastError();
  228. if (::boost::chrono::is_throws(ec))
  229. {
  230. boost::throw_exception(
  231. system::system_error(
  232. cause,
  233. ::boost::system::system_category(),
  234. "chrono::process_cpu_clock" ));
  235. }
  236. else
  237. {
  238. ec.assign( cause, ::boost::system::system_category() );
  239. return time_point();
  240. }
  241. }
  242. }
  243. #endif
  244. #endif
  245. } // namespace chrono
  246. } // namespace boost
  247. #endif