From 3e4c0f5aa33b5607dc05c9673ab891bdf4afbeb3 Mon Sep 17 00:00:00 2001 From: Darren Stahl Date: Tue, 15 Mar 2016 15:25:25 -0700 Subject: [PATCH] Fixes performance regression in GO 1.6 Signed-off-by: Darren Stahl --- file.go | 3 +++ zsyscall.go | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/file.go b/file.go index 02cd9a5..93c572b 100644 --- a/file.go +++ b/file.go @@ -13,6 +13,7 @@ import ( //sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort //sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus //sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes +//sys timeBeginPeriod(period uint32) (n int32) = TimeBeginPeriod const ( cFILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1 @@ -117,6 +118,8 @@ func (f *win32File) prepareIo() (*ioOperation, error) { // ioCompletionProcessor processes completed async IOs forever func ioCompletionProcessor(h syscall.Handle) { + // Set the timer resolution to 1. This fixes a performance regression in golang 1.6. + timeBeginPeriod(1) for { var bytes uint32 var key uintptr diff --git a/zsyscall.go b/zsyscall.go index eab955c..54b8332 100644 --- a/zsyscall.go +++ b/zsyscall.go @@ -15,6 +15,7 @@ var ( procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") + procTimeBeginPeriod = modkernel32.NewProc("TimeBeginPeriod") procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") procCreateFileW = modkernel32.NewProc("CreateFileW") @@ -88,6 +89,12 @@ func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err erro return } +func timeBeginPeriod(period uint32) (n int32) { + r0, _, _ := syscall.Syscall(procTimeBeginPeriod.Addr(), 1, uintptr(period), 0, 0) + n = int32(r0) + return +} + func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) { r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0) if r1 == 0 {