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
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.
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)
{
* 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();
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;