aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/netpoll_windows.go
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /libgo/go/runtime/netpoll_windows.go
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-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.go103
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