mirror of
https://github.com/golang/go
synced 2024-09-05 07:54:46 +00:00
runtime: revert "do not call timeBeginPeriod on windows"
This reverts commit ab4c9298b8
.
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 <austin@google.com>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
parent
9d4efdfd12
commit
0435e88a11
|
@ -120,7 +120,7 @@ func goEnv(key string) string {
|
||||||
func compilemain(t *testing.T, libgo string) {
|
func compilemain(t *testing.T, libgo string) {
|
||||||
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main.c")
|
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main.c")
|
||||||
if GOOS == "windows" {
|
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 {
|
} else {
|
||||||
ccArgs = append(ccArgs, "main_unix.c", libgo)
|
ccArgs = append(ccArgs, "main_unix.c", libgo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,11 @@ package runtime
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
var TestingWER = &testingWER
|
var (
|
||||||
var OsYield = osyield
|
TestingWER = &testingWER
|
||||||
|
OsYield = osyield
|
||||||
|
TimeBeginPeriodRetValue = &timeBeginPeriodRetValue
|
||||||
|
)
|
||||||
|
|
||||||
func NumberOfProcessors() int32 {
|
func NumberOfProcessors() int32 {
|
||||||
var info systeminfo
|
var info systeminfo
|
||||||
|
|
|
@ -53,6 +53,7 @@ const (
|
||||||
//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
|
//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._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
|
||||||
//go:cgo_import_dynamic runtime._WriteFile WriteFile%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
|
type stdFunction unsafe.Pointer
|
||||||
|
|
||||||
|
@ -98,7 +99,9 @@ var (
|
||||||
_WSAGetOverlappedResult,
|
_WSAGetOverlappedResult,
|
||||||
_WaitForSingleObject,
|
_WaitForSingleObject,
|
||||||
_WriteConsoleW,
|
_WriteConsoleW,
|
||||||
_WriteFile stdFunction
|
_WriteFile,
|
||||||
|
_timeBeginPeriod,
|
||||||
|
_ stdFunction
|
||||||
|
|
||||||
// Following syscalls are only available on some Windows PCs.
|
// Following syscalls are only available on some Windows PCs.
|
||||||
// We will load syscalls, if available, before using them.
|
// We will load syscalls, if available, before using them.
|
||||||
|
@ -228,6 +231,8 @@ func setlasterror(err uint32)
|
||||||
// flags can be used with LoadLibraryEx."
|
// flags can be used with LoadLibraryEx."
|
||||||
var useLoadLibraryEx bool
|
var useLoadLibraryEx bool
|
||||||
|
|
||||||
|
var timeBeginPeriodRetValue uint32
|
||||||
|
|
||||||
func osinit() {
|
func osinit() {
|
||||||
asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
|
asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
|
||||||
usleep2Addr = unsafe.Pointer(funcPC(usleep2))
|
usleep2Addr = unsafe.Pointer(funcPC(usleep2))
|
||||||
|
@ -247,6 +252,8 @@ func osinit() {
|
||||||
|
|
||||||
stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
|
stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
|
||||||
|
|
||||||
|
timeBeginPeriodRetValue = uint32(stdcall1(_timeBeginPeriod, 1))
|
||||||
|
|
||||||
ncpu = getproccount()
|
ncpu = getproccount()
|
||||||
|
|
||||||
// Windows dynamic priority boosting assumes that a process has different types
|
// 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.
|
// removeOneCPU removes one (any) cpu from affinity mask.
|
||||||
// It returns new affinity mask.
|
// It returns new affinity mask.
|
||||||
func removeOneCPU(mask uintptr) (uintptr, error) {
|
func removeOneCPU(mask uintptr) (uintptr, error) {
|
||||||
|
@ -874,21 +881,10 @@ var (
|
||||||
modwinmm = syscall.NewLazyDLL("winmm.dll")
|
modwinmm = syscall.NewLazyDLL("winmm.dll")
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
|
|
||||||
proctimeBeginPeriod = modwinmm.NewProc("timeBeginPeriod")
|
|
||||||
proctimeEndPeriod = modwinmm.NewProc("timeEndPeriod")
|
|
||||||
|
|
||||||
procCreateEvent = modkernel32.NewProc("CreateEventW")
|
procCreateEvent = modkernel32.NewProc("CreateEventW")
|
||||||
procSetEvent = modkernel32.NewProc("SetEvent")
|
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) {
|
func createEvent() (syscall.Handle, error) {
|
||||||
r0, _, e0 := syscall.Syscall6(procCreateEvent.Addr(), 4, 0, 0, 0, 0, 0, 0)
|
r0, _, e0 := syscall.Syscall6(procCreateEvent.Addr(), 4, 0, 0, 0, 0, 0, 0)
|
||||||
if r0 == 0 {
|
if r0 == 0 {
|
||||||
|
@ -905,7 +901,7 @@ func setEvent(h syscall.Handle) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func benchChanToSyscallPing(b *testing.B) {
|
func BenchmarkChanToSyscallPing(b *testing.B) {
|
||||||
n := b.N
|
n := b.N
|
||||||
ch := make(chan int)
|
ch := make(chan int)
|
||||||
event, err := createEvent()
|
event, err := createEvent()
|
||||||
|
@ -927,17 +923,7 @@ func benchChanToSyscallPing(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkChanToSyscallPing1ms(b *testing.B) {
|
func BenchmarkSyscallToSyscallPing(b *testing.B) {
|
||||||
timeBeginPeriod(1)
|
|
||||||
benchChanToSyscallPing(b)
|
|
||||||
timeEndPeriod(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChanToSyscallPing15ms(b *testing.B) {
|
|
||||||
benchChanToSyscallPing(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchSyscallToSyscallPing(b *testing.B) {
|
|
||||||
n := b.N
|
n := b.N
|
||||||
event1, err := createEvent()
|
event1, err := createEvent()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -965,17 +951,7 @@ func benchSyscallToSyscallPing(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkSyscallToSyscallPing1ms(b *testing.B) {
|
func BenchmarkChanToChanPing(b *testing.B) {
|
||||||
timeBeginPeriod(1)
|
|
||||||
benchSyscallToSyscallPing(b)
|
|
||||||
timeEndPeriod(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSyscallToSyscallPing15ms(b *testing.B) {
|
|
||||||
benchSyscallToSyscallPing(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchChanToChanPing(b *testing.B) {
|
|
||||||
n := b.N
|
n := b.N
|
||||||
ch1 := make(chan int)
|
ch1 := make(chan int)
|
||||||
ch2 := make(chan int)
|
ch2 := make(chan int)
|
||||||
|
@ -991,28 +967,8 @@ func benchChanToChanPing(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkChanToChanPing1ms(b *testing.B) {
|
func BenchmarkOsYield(b *testing.B) {
|
||||||
timeBeginPeriod(1)
|
|
||||||
benchChanToChanPing(b)
|
|
||||||
timeEndPeriod(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkChanToChanPing15ms(b *testing.B) {
|
|
||||||
benchChanToChanPing(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchOsYield(b *testing.B) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
runtime.OsYield()
|
runtime.OsYield()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkOsYield1ms(b *testing.B) {
|
|
||||||
timeBeginPeriod(1)
|
|
||||||
benchOsYield(b)
|
|
||||||
timeEndPeriod(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkOsYield15ms(b *testing.B) {
|
|
||||||
benchOsYield(b)
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue