aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2014-08-01 11:18:11 +1000
committerAlex Brainman <alex.brainman@gmail.com>2014-08-01 11:18:11 +1000
commit74b62b48644acffd20ca5de9111048dd731c3a06 (patch)
treef4c2a0670a2650aeeb486da7aacd71a94ad4831d /src/pkg/runtime
parent8ee2a6658b87eb14361b813d1f58d45df923427f (diff)
downloadgo-74b62b48644acffd20ca5de9111048dd731c3a06.tar.xz
runtime: implement monotonic clocks on windows
Update #6007. LGTM=minux, dvyukov R=golang-codereviews, dvyukov, patrick, aram.h, minux CC=golang-codereviews https://golang.org/cl/108700045
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/os_windows.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/src/pkg/runtime/os_windows.c b/src/pkg/runtime/os_windows.c
index 159af048f6..ee6eed002f 100644
--- a/src/pkg/runtime/os_windows.c
+++ b/src/pkg/runtime/os_windows.c
@@ -23,7 +23,6 @@
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
-#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
@@ -55,7 +54,6 @@ extern void *runtime·GetEnvironmentStringsW;
extern void *runtime·GetProcAddress;
extern void *runtime·GetStdHandle;
extern void *runtime·GetSystemInfo;
-extern void *runtime·GetSystemTimeAsFileTime;
extern void *runtime·GetThreadContext;
extern void *runtime·LoadLibrary;
extern void *runtime·LoadLibraryA;
@@ -265,17 +263,42 @@ runtime·unminit(void)
{
}
+// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
+typedef struct KSYSTEM_TIME {
+ uint32 LowPart;
+ int32 High1Time;
+ int32 High2Time;
+} KSYSTEM_TIME;
+
+const KSYSTEM_TIME* INTERRUPT_TIME = (KSYSTEM_TIME*)0x7ffe0008;
+const KSYSTEM_TIME* SYSTEM_TIME = (KSYSTEM_TIME*)0x7ffe0014;
+
#pragma textflag NOSPLIT
int64
-runtime·nanotime(void)
+runtime·systime(KSYSTEM_TIME *timeaddr)
{
- int64 filetime;
+ KSYSTEM_TIME t;
+ int32 i;
- runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
+ for(i = 0; i < 10000; i++) {
+ // these fields must be read in that order (see URL above)
+ t.High1Time = timeaddr->High1Time;
+ t.LowPart = timeaddr->LowPart;
+ t.High2Time = timeaddr->High2Time;
+ if(t.High1Time == t.High2Time)
+ return (int64)t.High1Time<<32 | t.LowPart;
+ if((i%100) == 0)
+ runtime·osyield();
+ }
+ runtime·throw("interrupt/system time is changing too fast");
+ return 0;
+}
- // Filetime is 100s of nanoseconds since January 1, 1601.
- // Convert to nanoseconds since January 1, 1970.
- return (filetime - 116444736000000000LL) * 100LL;
+#pragma textflag NOSPLIT
+int64
+runtime·nanotime(void)
+{
+ return runtime·systime(INTERRUPT_TIME) * 100LL;
}
void
@@ -283,7 +306,10 @@ time·now(int64 sec, int32 usec)
{
int64 ns;
- ns = runtime·nanotime();
+ // SystemTime is 100s of nanoseconds since January 1, 1601.
+ // Convert to nanoseconds since January 1, 1970.
+ ns = (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
+
sec = ns / 1000000000LL;
usec = ns - sec * 1000000000LL;
FLUSH(&sec);