|
23 | 23 | #pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
|
24 | 24 | #pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
|
25 | 25 | #pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
|
26 |
| -#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll" |
27 | 26 | #pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
|
28 | 27 | #pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
|
29 | 28 | #pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
|
@@ -55,7 +54,6 @@ extern void *runtime·GetEnvironmentStringsW;
|
55 | 54 | extern void *runtime·GetProcAddress;
|
56 | 55 | extern void *runtime·GetStdHandle;
|
57 | 56 | extern void *runtime·GetSystemInfo;
|
58 |
| -extern void *runtime·GetSystemTimeAsFileTime; |
59 | 57 | extern void *runtime·GetThreadContext;
|
60 | 58 | extern void *runtime·LoadLibrary;
|
61 | 59 | extern void *runtime·LoadLibraryA;
|
@@ -265,25 +263,53 @@ runtime·unminit(void)
|
265 | 263 | {
|
266 | 264 | }
|
267 | 265 |
|
| 266 | +// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/ |
| 267 | +typedef struct KSYSTEM_TIME { |
| 268 | + uint32 LowPart; |
| 269 | + int32 High1Time; |
| 270 | + int32 High2Time; |
| 271 | +} KSYSTEM_TIME; |
| 272 | + |
| 273 | +const KSYSTEM_TIME* INTERRUPT_TIME = (KSYSTEM_TIME*)0x7ffe0008; |
| 274 | +const KSYSTEM_TIME* SYSTEM_TIME = (KSYSTEM_TIME*)0x7ffe0014; |
| 275 | + |
268 | 276 | #pragma textflag NOSPLIT
|
269 | 277 | int64
|
270 |
| -runtime·nanotime(void) |
| 278 | +runtime·systime(KSYSTEM_TIME *timeaddr) |
271 | 279 | {
|
272 |
| - int64 filetime; |
273 |
| - |
274 |
| - runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime); |
| 280 | + KSYSTEM_TIME t; |
| 281 | + int32 i; |
| 282 | + |
| 283 | + for(i = 0; i < 10000; i++) { |
| 284 | + // these fields must be read in that order (see URL above) |
| 285 | + t.High1Time = timeaddr->High1Time; |
| 286 | + t.LowPart = timeaddr->LowPart; |
| 287 | + t.High2Time = timeaddr->High2Time; |
| 288 | + if(t.High1Time == t.High2Time) |
| 289 | + return (int64)t.High1Time<<32 | t.LowPart; |
| 290 | + if((i%100) == 0) |
| 291 | + runtime·osyield(); |
| 292 | + } |
| 293 | + runtime·throw("interrupt/system time is changing too fast"); |
| 294 | + return 0; |
| 295 | +} |
275 | 296 |
|
276 |
| - // Filetime is 100s of nanoseconds since January 1, 1601. |
277 |
| - // Convert to nanoseconds since January 1, 1970. |
278 |
| - return (filetime - 116444736000000000LL) * 100LL; |
| 297 | +#pragma textflag NOSPLIT |
| 298 | +int64 |
| 299 | +runtime·nanotime(void) |
| 300 | +{ |
| 301 | + return runtime·systime(INTERRUPT_TIME) * 100LL; |
279 | 302 | }
|
280 | 303 |
|
281 | 304 | void
|
282 | 305 | time·now(int64 sec, int32 usec)
|
283 | 306 | {
|
284 | 307 | int64 ns;
|
285 | 308 |
|
286 |
| - ns = runtime·nanotime(); |
| 309 | + // SystemTime is 100s of nanoseconds since January 1, 1601. |
| 310 | + // Convert to nanoseconds since January 1, 1970. |
| 311 | + ns = (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL; |
| 312 | + |
287 | 313 | sec = ns / 1000000000LL;
|
288 | 314 | usec = ns - sec * 1000000000LL;
|
289 | 315 | FLUSH(&sec);
|
|
0 commit comments