mirror of https://go.googlesource.com/go
71 lines
1.9 KiB
Go
71 lines
1.9 KiB
Go
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build windows
|
|
|
|
package testing
|
|
|
|
import (
|
|
"errors"
|
|
"internal/syscall/windows"
|
|
"math/bits"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// isWindowsRetryable reports whether err is a Windows error code
|
|
// that may be fixed by retrying a failed filesystem operation.
|
|
func isWindowsRetryable(err error) bool {
|
|
for {
|
|
unwrapped := errors.Unwrap(err)
|
|
if unwrapped == nil {
|
|
break
|
|
}
|
|
err = unwrapped
|
|
}
|
|
if err == syscall.ERROR_ACCESS_DENIED {
|
|
return true // Observed in https://go.dev/issue/50051.
|
|
}
|
|
if err == windows.ERROR_SHARING_VIOLATION {
|
|
return true // Observed in https://go.dev/issue/51442.
|
|
}
|
|
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)
|
|
}
|