Commit ea151041 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

net: band-aid for windows network poller

Fixes performance of the current windows network poller
with the new scheduler.
Gives runtime a hint when GetQueuedCompletionStatus() will block.
Fixes #5068.

benchmark                    old ns/op    new ns/op    delta
BenchmarkTCP4Persistent        4004000        33906  -99.15%
BenchmarkTCP4Persistent-2        21790        17513  -19.63%
BenchmarkTCP4Persistent-4        44760        34270  -23.44%
BenchmarkTCP4Persistent-6        45280        43000   -5.04%

R=golang-dev, alex.brainman, coocood, rsc
CC=golang-dev
https://golang.org/cl/7612045
parent 4ad1a87f
...@@ -138,12 +138,18 @@ type resultSrv struct { ...@@ -138,12 +138,18 @@ type resultSrv struct {
iocp syscall.Handle iocp syscall.Handle
} }
func runtime_blockingSyscallHint()
func (s *resultSrv) Run() { func (s *resultSrv) Run() {
var o *syscall.Overlapped var o *syscall.Overlapped
var key uint32 var key uint32
var r ioResult var r ioResult
for { for {
r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, syscall.INFINITE) r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, 0)
if r.err == syscall.Errno(syscall.WAIT_TIMEOUT) && o == nil {
runtime_blockingSyscallHint()
r.err = syscall.GetQueuedCompletionStatus(s.iocp, &(r.qty), &key, &o, syscall.INFINITE)
}
switch { switch {
case r.err == nil: case r.err == nil:
// Dequeued successfully completed IO packet. // Dequeued successfully completed IO packet.
......
...@@ -98,6 +98,15 @@ static void unwindm(void); ...@@ -98,6 +98,15 @@ static void unwindm(void);
static void endcgo(void); static void endcgo(void);
static FuncVal endcgoV = { endcgo }; static FuncVal endcgoV = { endcgo };
// Gives a hint that the next syscall
// executed by the current goroutine will block.
// Currently used only on windows.
void
net·runtime_blockingSyscallHint(void)
{
g->blockingsyscall = true;
}
void void
runtime·cgocall(void (*fn)(void*), void *arg) runtime·cgocall(void (*fn)(void*), void *arg)
{ {
...@@ -145,7 +154,11 @@ runtime·cgocall(void (*fn)(void*), void *arg) ...@@ -145,7 +154,11 @@ runtime·cgocall(void (*fn)(void*), void *arg)
* so it is safe to call while "in a system call", outside * so it is safe to call while "in a system call", outside
* the $GOMAXPROCS accounting. * the $GOMAXPROCS accounting.
*/ */
runtime·entersyscall(); if(g->blockingsyscall) {
g->blockingsyscall = false;
runtime·entersyscallblock();
} else
runtime·entersyscall();
runtime·asmcgocall(fn, arg); runtime·asmcgocall(fn, arg);
runtime·exitsyscall(); runtime·exitsyscall();
......
...@@ -238,6 +238,7 @@ struct G ...@@ -238,6 +238,7 @@ struct G
bool ispanic; bool ispanic;
bool issystem; // do not output in stack dump bool issystem; // do not output in stack dump
bool isbackground; // ignore in deadlock detector bool isbackground; // ignore in deadlock detector
bool blockingsyscall; // hint that the next syscall will block
int8 raceignore; // ignore race detection events int8 raceignore; // ignore race detection events
M* m; // for debuggers, but offset not hard-coded M* m; // for debuggers, but offset not hard-coded
M* lockedm; M* lockedm;
......
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