diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-08-22 17:43:43 -0300 |
commit | a926878ddbd5a98b272c22171ce58663fc04c3e0 (patch) | |
tree | 86af256e5d9a9c06263c00adc90e5fe348008c43 /libgo/go/runtime/netpoll_windows.go | |
parent | 542730f087133690b47e036dfd43eb0db8a650ce (diff) | |
parent | 07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff) | |
download | gcc-devel/autopar_devel.zip gcc-devel/autopar_devel.tar.gz gcc-devel/autopar_devel.tar.bz2 |
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'libgo/go/runtime/netpoll_windows.go')
-rw-r--r-- | libgo/go/runtime/netpoll_windows.go | 103 |
1 files changed, 38 insertions, 65 deletions
diff --git a/libgo/go/runtime/netpoll_windows.go b/libgo/go/runtime/netpoll_windows.go index ced52cb..4c1cd26 100644 --- a/libgo/go/runtime/netpoll_windows.go +++ b/libgo/go/runtime/netpoll_windows.go @@ -5,6 +5,7 @@ package runtime import ( + "runtime/internal/atomic" "unsafe" ) @@ -31,7 +32,11 @@ type overlappedEntry struct { qty uint32 } -var iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle +var ( + iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle + + netpollWakeSig uint32 // used to avoid duplicate calls of netpollBreak +) func netpollinit() { iocphandle = stdcall4(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX) @@ -62,9 +67,11 @@ func netpollarm(pd *pollDesc, mode int) { } func netpollBreak() { - if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 { - println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")") - throw("runtime: netpoll: PostQueuedCompletionStatus failed") + if atomic.Cas(&netpollWakeSig, 0, 1) { + if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 { + println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")") + throw("runtime: netpoll: PostQueuedCompletionStatus failed") + } } } @@ -75,7 +82,7 @@ func netpollBreak() { // delay > 0: block for up to that many nanoseconds func netpoll(delay int64) gList { var entries [64]overlappedEntry - var wait, qty, key, flags, n, i uint32 + var wait, qty, flags, n, i uint32 var errno int32 var op *net_op var toRun gList @@ -99,82 +106,48 @@ func netpoll(delay int64) gList { wait = 1e9 } - if _GetQueuedCompletionStatusEx != nil { - n = uint32(len(entries) / int(gomaxprocs)) - if n < 8 { - n = 8 - } - if delay != 0 { - mp.blocked = true - } - if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") - throw("runtime: netpoll failed") - } + n = uint32(len(entries) / int(gomaxprocs)) + if n < 8 { + n = 8 + } + if delay != 0 { + mp.blocked = true + } + if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 { mp.blocked = false - for i = 0; i < n; i++ { - op = entries[i].op - if op != nil { - errno = 0 - qty = 0 - if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { - errno = int32(getlasterror()) - } - handlecompletion(&toRun, op, errno, qty) - } else { - if delay == 0 { - // Forward the notification to the - // blocked poller. - netpollBreak() - } - } - } - } else { - op = nil - errno = 0 - qty = 0 - if delay != 0 { - mp.blocked = true + errno = int32(getlasterror()) + if errno == _WAIT_TIMEOUT { + return gList{} } - if stdcall5(_GetQueuedCompletionStatus, iocphandle, uintptr(unsafe.Pointer(&qty)), uintptr(unsafe.Pointer(&key)), uintptr(unsafe.Pointer(&op)), uintptr(wait)) == 0 { - mp.blocked = false - errno = int32(getlasterror()) - if errno == _WAIT_TIMEOUT { - return gList{} - } - if op == nil { - println("runtime: GetQueuedCompletionStatus failed (errno=", errno, ")") - throw("runtime: netpoll failed") + println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")") + throw("runtime: netpoll failed") + } + mp.blocked = false + for i = 0; i < n; i++ { + op = entries[i].op + if op != nil { + errno = 0 + qty = 0 + if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 { + errno = int32(getlasterror()) } - // dequeued failed IO packet, so report that - } - mp.blocked = false - if op == nil { + handlecompletion(&toRun, op, errno, qty) + } else { + atomic.Store(&netpollWakeSig, 0) if delay == 0 { // Forward the notification to the // blocked poller. netpollBreak() } - return gList{} } - handlecompletion(&toRun, op, errno, qty) } return toRun } func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) { - if op == nil { - println("runtime: GetQueuedCompletionStatus returned op == nil") - throw("runtime: netpoll failed") - } mode := op.mode if mode != 'r' && mode != 'w' { - println("runtime: GetQueuedCompletionStatus returned invalid mode=", mode) + println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode) throw("runtime: netpoll failed") } op.errno = errno |