Skip to content

Commit

Permalink
runtime: revert "do not call timeBeginPeriod on windows"
Browse files Browse the repository at this point in the history
This reverts commit ab4c929.

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/20834
Reviewed-by: Austin Clements <[email protected]>
Run-TryBot: Dmitry Vyukov <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Alex Brainman <[email protected]>
  • Loading branch information
dvyukov committed Apr 9, 2016
1 parent 9d4efdf commit 0435e88
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 59 deletions.
2 changes: 1 addition & 1 deletion misc/cgo/testcarchive/carchive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/export_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion src/runtime/os_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand All @@ -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
Expand Down
66 changes: 11 additions & 55 deletions src/runtime/syscall_windows_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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()
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
Expand All @@ -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)
}

0 comments on commit 0435e88

Please sign in to comment.