Commit 0435e88a authored by Dmitry Vyukov's avatar Dmitry Vyukov

runtime: revert "do not call timeBeginPeriod on windows"

This reverts commit ab4c9298.

Sysmon critically depends on system timer resolution for retaking
of Ps blocked in system calls. See #14790 for an example
of a program where execution time goes from 2ms to 30ms if
timeBeginPeriod(1) is not used.

We can remove timeBeginPeriod(1) when we support UMS (#7876).

Update #14790

Change-Id: I362b56154359b2c52d47f9f2468fe012b481cf6d
Reviewed-on: https://go-review.googlesource.com/20834Reviewed-by: 's avatarAustin Clements <austin@google.com>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarAlex Brainman <alex.brainman@gmail.com>
parent 9d4efdfd
......@@ -120,7 +120,7 @@ func goEnv(key string) string {
func compilemain(t *testing.T, libgo string) {
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main.c")
if GOOS == "windows" {
ccArgs = append(ccArgs, "main_windows.c", libgo, "-lntdll", "-lws2_32")
ccArgs = append(ccArgs, "main_windows.c", libgo, "-lntdll", "-lws2_32", "-lwinmm")
} else {
ccArgs = append(ccArgs, "main_unix.c", libgo)
}
......
......@@ -8,8 +8,11 @@ package runtime
import "unsafe"
var TestingWER = &testingWER
var OsYield = osyield
var (
TestingWER = &testingWER
OsYield = osyield
TimeBeginPeriodRetValue = &timeBeginPeriodRetValue
)
func NumberOfProcessors() int32 {
var info systeminfo
......
......@@ -53,6 +53,7 @@ const (
//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll"
type stdFunction unsafe.Pointer
......@@ -98,7 +99,9 @@ var (
_WSAGetOverlappedResult,
_WaitForSingleObject,
_WriteConsoleW,
_WriteFile stdFunction
_WriteFile,
_timeBeginPeriod,
_ stdFunction
// Following syscalls are only available on some Windows PCs.
// We will load syscalls, if available, before using them.
......@@ -228,6 +231,8 @@ func setlasterror(err uint32)
// flags can be used with LoadLibraryEx."
var useLoadLibraryEx bool
var timeBeginPeriodRetValue uint32
func osinit() {
asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
usleep2Addr = unsafe.Pointer(funcPC(usleep2))
......@@ -247,6 +252,8 @@ func osinit() {
stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
timeBeginPeriodRetValue = uint32(stdcall1(_timeBeginPeriod, 1))
ncpu = getproccount()
// Windows dynamic priority boosting assumes that a process has different types
......
......@@ -622,6 +622,13 @@ uintptr_t cfunc(callback f, uintptr_t n) {
}
}
func TestTimeBeginPeriod(t *testing.T) {
const TIMERR_NOERROR = 0
if *runtime.TimeBeginPeriodRetValue != TIMERR_NOERROR {
t.Fatalf("timeBeginPeriod failed: it returned %d", *runtime.TimeBeginPeriodRetValue)
}
}
// removeOneCPU removes one (any) cpu from affinity mask.
// It returns new affinity mask.
func removeOneCPU(mask uintptr) (uintptr, error) {
......@@ -874,21 +881,10 @@ var (
modwinmm = syscall.NewLazyDLL("winmm.dll")
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod")
proctimeEndPeriod = modwinmm.NewProc("timeEndPeriod")
procCreateEvent = modkernel32.NewProc("CreateEventW")
procSetEvent = modkernel32.NewProc("SetEvent")
)
func timeBeginPeriod(period uint32) {
syscall.Syscall(proctimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0)
}
func timeEndPeriod(period uint32) {
syscall.Syscall(proctimeEndPeriod.Addr(), 1, uintptr(period), 0, 0)
}
func createEvent() (syscall.Handle, error) {
r0, _, e0 := syscall.Syscall6(procCreateEvent.Addr(), 4, 0, 0, 0, 0, 0, 0)
if r0 == 0 {
......@@ -905,7 +901,7 @@ func setEvent(h syscall.Handle) error {
return nil
}
func benchChanToSyscallPing(b *testing.B) {
func BenchmarkChanToSyscallPing(b *testing.B) {
n := b.N
ch := make(chan int)
event, err := createEvent()
......@@ -927,17 +923,7 @@ func benchChanToSyscallPing(b *testing.B) {
}
}
func BenchmarkChanToSyscallPing1ms(b *testing.B) {
timeBeginPeriod(1)
benchChanToSyscallPing(b)
timeEndPeriod(1)
}
func BenchmarkChanToSyscallPing15ms(b *testing.B) {
benchChanToSyscallPing(b)
}
func benchSyscallToSyscallPing(b *testing.B) {
func BenchmarkSyscallToSyscallPing(b *testing.B) {
n := b.N
event1, err := createEvent()
if err != nil {
......@@ -965,17 +951,7 @@ func benchSyscallToSyscallPing(b *testing.B) {
}
}
func BenchmarkSyscallToSyscallPing1ms(b *testing.B) {
timeBeginPeriod(1)
benchSyscallToSyscallPing(b)
timeEndPeriod(1)
}
func BenchmarkSyscallToSyscallPing15ms(b *testing.B) {
benchSyscallToSyscallPing(b)
}
func benchChanToChanPing(b *testing.B) {
func BenchmarkChanToChanPing(b *testing.B) {
n := b.N
ch1 := make(chan int)
ch2 := make(chan int)
......@@ -991,28 +967,8 @@ func benchChanToChanPing(b *testing.B) {
}
}
func BenchmarkChanToChanPing1ms(b *testing.B) {
timeBeginPeriod(1)
benchChanToChanPing(b)
timeEndPeriod(1)
}
func BenchmarkChanToChanPing15ms(b *testing.B) {
benchChanToChanPing(b)
}
func benchOsYield(b *testing.B) {
func BenchmarkOsYield(b *testing.B) {
for i := 0; i < b.N; i++ {
runtime.OsYield()
}
}
func BenchmarkOsYield1ms(b *testing.B) {
timeBeginPeriod(1)
benchOsYield(b)
timeEndPeriod(1)
}
func BenchmarkOsYield15ms(b *testing.B) {
benchOsYield(b)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment