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