diff options
Diffstat (limited to 'src/testing/testing_windows.go')
-rw-r--r-- | src/testing/testing_windows.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/testing/testing_windows.go b/src/testing/testing_windows.go index fd48ae9579..ebe4e01d23 100644 --- a/src/testing/testing_windows.go +++ b/src/testing/testing_windows.go @@ -9,7 +9,9 @@ package testing import ( "errors" "internal/syscall/windows" + "math/bits" "syscall" + "time" ) // isWindowsRetryable reports whether err is a Windows error code @@ -30,3 +32,39 @@ func isWindowsRetryable(err error) bool { } return false } + +// highPrecisionTime represents a single point in time with query performance counter. +// time.Time on Windows has low system granularity, which is not suitable for +// measuring short time intervals. +// +// TODO: If Windows runtime implements high resolution timing then highPrecisionTime +// can be removed. +type highPrecisionTime struct { + now int64 +} + +// highPrecisionTimeNow returns high precision time for benchmarking. +func highPrecisionTimeNow() highPrecisionTime { + var t highPrecisionTime + // This should always succeed for Windows XP and above. + t.now = windows.QueryPerformanceCounter() + return t +} + +func (a highPrecisionTime) sub(b highPrecisionTime) time.Duration { + delta := a.now - b.now + + if queryPerformanceFrequency == 0 { + queryPerformanceFrequency = windows.QueryPerformanceFrequency() + } + hi, lo := bits.Mul64(uint64(delta), uint64(time.Second)/uint64(time.Nanosecond)) + quo, _ := bits.Div64(hi, lo, uint64(queryPerformanceFrequency)) + return time.Duration(quo) +} + +var queryPerformanceFrequency int64 + +// highPrecisionTimeSince returns duration since a. +func highPrecisionTimeSince(a highPrecisionTime) time.Duration { + return highPrecisionTimeNow().sub(a) +} |