Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(205)

Delta Between Two Patch Sets: Python/pytime.c

Issue 22043: Use a monotonic clock to compute timeouts
Left Patch Set: Created 3 years ago
Right Patch Set: Created 3 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Modules/timemodule.c ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #include "Python.h" 1 #include "Python.h"
2 #ifdef MS_WINDOWS 2 #ifdef MS_WINDOWS
3 #include <windows.h> 3 #include <windows.h>
4 #endif 4 #endif
5 5
6 #if defined(__APPLE__) 6 #if defined(__APPLE__)
7 #include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */ 7 #include <mach/mach_time.h> /* mach_absolute_time(), mach_timebase_info() */
8 #endif 8 #endif
9 9
10 #ifdef MS_WINDOWS 10 #ifdef MS_WINDOWS
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 { 119 {
120 return pygettimeofday(tp, info, 1); 120 return pygettimeofday(tp, info, 1);
121 } 121 }
122 122
123 static int 123 static int
124 pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise) 124 pymonotonic(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
125 { 125 {
126 #if defined(MS_WINDOWS) 126 #if defined(MS_WINDOWS)
127 static ULONGLONG (*GetTickCount64) (void) = NULL; 127 static ULONGLONG (*GetTickCount64) (void) = NULL;
128 static ULONGLONG (CALLBACK *Py_GetTickCount64)(void); 128 static ULONGLONG (CALLBACK *Py_GetTickCount64)(void);
129 static int has_getickcount64 = -1; 129 static int has_gettickcount64 = -1;
AntoinePitrou 2014/08/31 02:24:18 You should fix the typo in the variable name.
haypo 2014/08/31 15:02:33 Oh, I just moved the code from timemodule.c. But o
130 ULONGLONG result; 130 ULONGLONG result;
131 131
132 assert(info == NULL || raise); 132 assert(info == NULL || raise);
133 133
134 if (has_getickcount64 == -1) { 134 if (has_gettickcount64 == -1) {
135 /* GetTickCount64() was added to Windows Vista */ 135 /* GetTickCount64() was added to Windows Vista */
136 if (winver.dwMajorVersion >= 6) { 136 has_gettickcount64 = (winver.dwMajorVersion >= 6);
137 if (has_gettickcount64) {
137 HINSTANCE hKernel32; 138 HINSTANCE hKernel32;
138 hKernel32 = GetModuleHandleW(L"KERNEL32"); 139 hKernel32 = GetModuleHandleW(L"KERNEL32");
139 *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32, 140 *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32,
140 "GetTickCount64"); 141 "GetTickCount64");
141 has_getickcount64 = (Py_GetTickCount64 != NULL); 142 assert(Py_GetTickCount64 != NULL);
AntoinePitrou 2014/08/31 02:24:18 Is it expected to fail?
haypo 2014/08/31 15:02:33 MSDN documentation says that GetTickCount64() is a
142 } 143 }
143 else 144 }
144 has_getickcount64 = 0; 145
145 } 146 if (has_gettickcount64) {
146
147 if (has_getickcount64) {
148 result = Py_GetTickCount64(); 147 result = Py_GetTickCount64();
149 } 148 }
150 else { 149 else {
151 static DWORD last_ticks = 0; 150 static DWORD last_ticks = 0;
152 static DWORD n_overflow = 0; 151 static DWORD n_overflow = 0;
153 DWORD ticks; 152 DWORD ticks;
154 153
155 ticks = GetTickCount(); 154 ticks = GetTickCount();
156 if (ticks < last_ticks) 155 if (ticks < last_ticks)
157 n_overflow++; 156 n_overflow++;
158 last_ticks = ticks; 157 last_ticks = ticks;
159 158
160 result = (ULONGLONG)n_overflow << 32; 159 result = (ULONGLONG)n_overflow << 32;
161 result += ticks; 160 result += ticks;
162 } 161 }
163 162
164 tp->tv_sec = result / 1000; 163 tp->tv_sec = result / 1000;
165 tp->tv_usec = (result % 1000) * 1000; 164 tp->tv_usec = (result % 1000) * 1000;
166 165
167 if (info) { 166 if (info) {
168 DWORD timeAdjustment, timeIncrement; 167 DWORD timeAdjustment, timeIncrement;
169 BOOL isTimeAdjustmentDisabled, ok; 168 BOOL isTimeAdjustmentDisabled, ok;
170 if (has_getickcount64) 169 if (has_gettickcount64)
171 info->implementation = "GetTickCount64()"; 170 info->implementation = "GetTickCount64()";
172 else 171 else
173 info->implementation = "GetTickCount()"; 172 info->implementation = "GetTickCount()";
174 info->monotonic = 1; 173 info->monotonic = 1;
175 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, 174 ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
176 &isTimeAdjustmentDisabled); 175 &isTimeAdjustmentDisabled);
177 if (!ok) { 176 if (!ok) {
178 PyErr_SetFromWindowsErr(0); 177 PyErr_SetFromWindowsErr(0);
179 return -1; 178 return -1;
180 } 179 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 222
224 assert(info == NULL || raise); 223 assert(info == NULL || raise);
225 224
226 if (clock_gettime(clk_id, &ts) != 0) { 225 if (clock_gettime(clk_id, &ts) != 0) {
227 if (raise) { 226 if (raise) {
228 PyErr_SetFromErrno(PyExc_OSError); 227 PyErr_SetFromErrno(PyExc_OSError);
229 return -1; 228 return -1;
230 } 229 }
231 tp->tv_sec = 0; 230 tp->tv_sec = 0;
232 tp->tv_usec = 0; 231 tp->tv_usec = 0;
233 return -1; 232 return -1;
AntoinePitrou 2014/08/31 02:24:18 The doc in pytime.h says that "the function never
haypo 2014/08/31 15:02:33 _PyTime_monotonic() never fails, _PyTime_monotonic
234 } 233 }
235 234
236 if (info) { 235 if (info) {
237 struct timespec res; 236 struct timespec res;
238 info->monotonic = 1; 237 info->monotonic = 1;
239 info->implementation = implementation; 238 info->implementation = implementation;
240 info->adjustable = 0; 239 info->adjustable = 0;
241 if (clock_getres(clk_id, &res) != 0) { 240 if (clock_getres(clk_id, &res) != 0) {
242 PyErr_SetFromErrno(PyExc_OSError); 241 PyErr_SetFromErrno(PyExc_OSError);
243 return -1; 242 return -1;
244 } 243 }
245 info->resolution = res.tv_sec + res.tv_nsec * 1e-9; 244 info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
246 } 245 }
247 tp->tv_sec = ts.tv_sec; 246 tp->tv_sec = ts.tv_sec;
248 tp->tv_usec = ts.tv_nsec / 1000; 247 tp->tv_usec = ts.tv_nsec / 1000;
249 return 0; 248 return 0;
250 #endif 249 #endif
251 } 250 }
252 251
253 void 252 void
254 _PyTime_monotonic(_PyTime_timeval *tp) 253 _PyTime_monotonic(_PyTime_timeval *tp)
255 { 254 {
256 if (pymonotonic(tp, NULL, 0) < 0) { 255 if (pymonotonic(tp, NULL, 0) < 0) {
257 /* cannot happen, _PyTime_Init() checks that pygettimeofday() works */ 256 /* cannot happen, _PyTime_Init() checks that pymonotonic() works */
AntoinePitrou 2014/08/31 02:24:18 s/pygettimeofday/pymonotonic/
258 assert(0); 257 assert(0);
259 tp->tv_sec = 0; 258 tp->tv_sec = 0;
260 tp->tv_usec = 0; 259 tp->tv_usec = 0;
261 } 260 }
262 } 261 }
263 262
264 int 263 int
265 _PyTime_monotonic_info(_PyTime_timeval *tp, _Py_clock_info_t *info) 264 _PyTime_monotonic_info(_PyTime_timeval *tp, _Py_clock_info_t *info)
266 { 265 {
267 return pymonotonic(tp, info, 1); 266 return pymonotonic(tp, info, 1);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 413
415 /* ensure that the system clock works */ 414 /* ensure that the system clock works */
416 if (_PyTime_gettimeofday_info(&tv, NULL) < 0) 415 if (_PyTime_gettimeofday_info(&tv, NULL) < 0)
417 return -1; 416 return -1;
418 417
419 /* ensure that the operating system provides a monotonic clock */ 418 /* ensure that the operating system provides a monotonic clock */
420 if (_PyTime_monotonic_info(&tv, NULL) < 0) 419 if (_PyTime_monotonic_info(&tv, NULL) < 0)
421 return -1; 420 return -1;
422 return 0; 421 return 0;
423 } 422 }
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7