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