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
diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go
index 0e331b4..cacee62 100644
--- a/src/pkg/net/fd_windows.go
+++ b/src/pkg/net/fd_windows.go
@@ -138,12 +138,18 @@
 	iocp syscall.Handle
 }
 
+func runtime_blockingSyscallHint()
+
 func (s *resultSrv) Run() {
 	var o *syscall.Overlapped
 	var key uint32
 	var r ioResult
 	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 {
 		case r.err == nil:
 			// Dequeued successfully completed IO packet.
diff --git a/src/pkg/runtime/cgocall.c b/src/pkg/runtime/cgocall.c
index 0c96187..b829665 100644
--- a/src/pkg/runtime/cgocall.c
+++ b/src/pkg/runtime/cgocall.c
@@ -98,6 +98,15 @@
 static void endcgo(void);
 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
 runtime·cgocall(void (*fn)(void*), void *arg)
 {
@@ -145,7 +154,11 @@
 	 * so it is safe to call while "in a system call", outside
 	 * the $GOMAXPROCS accounting.
 	 */
-	runtime·entersyscall();
+	if(g->blockingsyscall) {
+		g->blockingsyscall = false;
+		runtime·entersyscallblock();
+	} else
+		runtime·entersyscall();
 	runtime·asmcgocall(fn, arg);
 	runtime·exitsyscall();
 
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 46c77e3..638acd4 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -238,6 +238,7 @@
 	bool	ispanic;
 	bool	issystem;	// do not output in stack dump
 	bool	isbackground;	// ignore in deadlock detector
+	bool	blockingsyscall;	// hint that the next syscall will block
 	int8	raceignore;	// ignore race detection events
 	M*	m;		// for debuggers, but offset not hard-coded
 	M*	lockedm;