]> Cypherpunks repositories - gostls13.git/commitdiff
net: band-aid for windows network poller
authorDmitriy Vyukov <dvyukov@google.com>
Mon, 25 Mar 2013 16:57:36 +0000 (20:57 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Mon, 25 Mar 2013 16:57:36 +0000 (20:57 +0400)
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

src/pkg/net/fd_windows.go
src/pkg/runtime/cgocall.c
src/pkg/runtime/runtime.h

index 0e331b44dc82eae2d7c9f816a034066403fc34e4..cacee627b622e44c385b9f9803e8031c07e84895 100644 (file)
@@ -138,12 +138,18 @@ type resultSrv struct {
        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.
index 0c96187495312a8682d7823a24d0f91225b930d4..b829665462399ecdcf4a5c1dc37edfbd4fb5b6df 100644 (file)
@@ -98,6 +98,15 @@ static void unwindm(void);
 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 @@ runtime·cgocall(void (*fn)(void*), void *arg)
         * 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();
 
index 46c77e3fd5e221882e189be183fef91c4b07382c..638acd4740ce99a54f8f9d57cab3e11ca44bf40e 100644 (file)
@@ -238,6 +238,7 @@ struct      G
        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;