aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/netpoll_epoll.go
diff options
context:
space:
mode:
authorAndrew Pogrebnoy <absourd.noise@gmail.com>2022-08-01 17:58:17 +0300
committerGopher Robot <gobot@golang.org>2022-09-30 17:35:24 +0000
commit4e6f963469d8f489586b2bf277af30e0fbfa1679 (patch)
tree78a0af19244b856a0845b997d72324f16b6d0457 /src/runtime/netpoll_epoll.go
parent9e0149da3c25c3a2399e0f578549f252c186491c (diff)
downloadgo-4e6f963469d8f489586b2bf277af30e0fbfa1679.tar.gz
go-4e6f963469d8f489586b2bf277af30e0fbfa1679.zip
runtime: move epoll syscalls to runtime/internal/syscall
This change moves Linux epoll's syscalls implementation to the "runtime/internal/syscall" package. The intention in this CL was to minimise behavioural changes but make the code more generalised. This also will allow adding new syscalls (like epoll_pwait2) without the need to implement assembly stubs for each arch. It also drops epoll_create as not all architectures provide this call. epoll_create1 was added to the kernel in version 2.6.27 and Go requires Linux kernel version 2.6.32 or later since Go 1.18. So it is safe to always use epoll_create1. For #53824 For #51087 Change-Id: I9a6a26b7f2075a38e041de1bab4691da0ecb94fc Reviewed-on: https://go-review.googlesource.com/c/go/+/421994 Reviewed-by: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src/runtime/netpoll_epoll.go')
-rw-r--r--src/runtime/netpoll_epoll.go84
1 files changed, 36 insertions, 48 deletions
diff --git a/src/runtime/netpoll_epoll.go b/src/runtime/netpoll_epoll.go
index 09da662c92..7164a59551 100644
--- a/src/runtime/netpoll_epoll.go
+++ b/src/runtime/netpoll_epoll.go
@@ -8,19 +8,10 @@ package runtime
import (
"runtime/internal/atomic"
+ "runtime/internal/syscall"
"unsafe"
)
-func epollcreate(size int32) int32
-func epollcreate1(flags int32) int32
-
-//go:noescape
-func epollctl(epfd, op, fd int32, ev *epollevent) int32
-
-//go:noescape
-func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
-func closeonexec(fd int32)
-
var (
epfd int32 = -1 // epoll descriptor
@@ -30,27 +21,24 @@ var (
)
func netpollinit() {
- epfd = epollcreate1(_EPOLL_CLOEXEC)
- if epfd < 0 {
- epfd = epollcreate(1024)
- if epfd < 0 {
- println("runtime: epollcreate failed with", -epfd)
- throw("runtime: netpollinit failed")
- }
- closeonexec(epfd)
- }
- r, w, errno := nonblockingPipe()
+ var errno uintptr
+ epfd, errno = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC)
if errno != 0 {
- println("runtime: pipe failed with", -errno)
+ println("runtime: epollcreate failed with", errno)
+ throw("runtime: netpollinit failed")
+ }
+ r, w, errpipe := nonblockingPipe()
+ if errpipe != 0 {
+ println("runtime: pipe failed with", -errpipe)
throw("runtime: pipe failed")
}
- ev := epollevent{
- events: _EPOLLIN,
+ ev := syscall.EpollEvent{
+ Events: syscall.EPOLLIN,
}
- *(**uintptr)(unsafe.Pointer(&ev.data)) = &netpollBreakRd
- errno = epollctl(epfd, _EPOLL_CTL_ADD, r, &ev)
+ *(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollBreakRd
+ errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, r, &ev)
if errno != 0 {
- println("runtime: epollctl failed with", -errno)
+ println("runtime: epollctl failed with", errno)
throw("runtime: epollctl failed")
}
netpollBreakRd = uintptr(r)
@@ -61,16 +49,16 @@ func netpollIsPollDescriptor(fd uintptr) bool {
return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr
}
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
- var ev epollevent
- ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
- *(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
- return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
+func netpollopen(fd uintptr, pd *pollDesc) uintptr {
+ var ev syscall.EpollEvent
+ ev.Events = syscall.EPOLLIN | syscall.EPOLLOUT | syscall.EPOLLRDHUP | syscall.EPOLLET
+ *(**pollDesc)(unsafe.Pointer(&ev.Data)) = pd
+ return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int32(fd), &ev)
}
-func netpollclose(fd uintptr) int32 {
- var ev epollevent
- return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
+func netpollclose(fd uintptr) uintptr {
+ var ev syscall.EpollEvent
+ return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int32(fd), &ev)
}
func netpollarm(pd *pollDesc, mode int) {
@@ -124,12 +112,12 @@ func netpoll(delay int64) gList {
// 1e9 ms == ~11.5 days.
waitms = 1e9
}
- var events [128]epollevent
+ var events [128]syscall.EpollEvent
retry:
- n := epollwait(epfd, &events[0], int32(len(events)), waitms)
- if n < 0 {
- if n != -_EINTR {
- println("runtime: epollwait on fd", epfd, "failed with", -n)
+ n, errno := syscall.EpollWait(epfd, events[:], int32(len(events)), waitms)
+ if errno != 0 {
+ if errno != _EINTR {
+ println("runtime: epollwait on fd", epfd, "failed with", errno)
throw("runtime: netpoll failed")
}
// If a timed sleep was interrupted, just return to
@@ -141,14 +129,14 @@ retry:
}
var toRun gList
for i := int32(0); i < n; i++ {
- ev := &events[i]
- if ev.events == 0 {
+ ev := events[i]
+ if ev.Events == 0 {
continue
}
- if *(**uintptr)(unsafe.Pointer(&ev.data)) == &netpollBreakRd {
- if ev.events != _EPOLLIN {
- println("runtime: netpoll: break fd ready for", ev.events)
+ if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollBreakRd {
+ if ev.Events != syscall.EPOLLIN {
+ println("runtime: netpoll: break fd ready for", ev.Events)
throw("runtime: netpoll: break fd ready for something unexpected")
}
if delay != 0 {
@@ -163,15 +151,15 @@ retry:
}
var mode int32
- if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
+ if ev.Events&(syscall.EPOLLIN|syscall.EPOLLRDHUP|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
mode += 'r'
}
- if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
+ if ev.Events&(syscall.EPOLLOUT|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
mode += 'w'
}
if mode != 0 {
- pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
- pd.setEventErr(ev.events == _EPOLLERR)
+ pd := *(**pollDesc)(unsafe.Pointer(&ev.Data))
+ pd.setEventErr(ev.Events == syscall.EPOLLERR)
netpollready(&toRun, pd, mode)
}
}