]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: utilize EVFILT_USER more effectively
authorMaksym Sobolyev <sobomax@sippysoft.com>
Wed, 20 Nov 2024 19:27:40 +0000 (19:27 +0000)
committerGopher Robot <gobot@golang.org>
Thu, 21 Nov 2024 16:24:21 +0000 (16:24 +0000)
Re-work kqueue_event wakeup logic to use one-shot events. In an
event of waking up a wrong thread, simply re-post the event.

This saves close to 1 system call per wakeup on average, since
chances of non-blocking poller picking it up is pretty low.

Change-Id: I202d0d57a31d91ac5354ea075215f647c65790d3
GitHub-Last-Rev: e707d4732683702bd2989f07230a2f34354c288b
GitHub-Pull-Request: golang/go#70408
Reviewed-on: https://go-review.googlesource.com/c/go/+/628975
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/runtime/netpoll_kqueue.go
src/runtime/netpoll_kqueue_event.go
src/runtime/netpoll_kqueue_pipe.go

index ca7898205e0ad6749fbca127b169a6d3b3ea08ff..db4dddc2fe04c7d82e28558ae9ff228974ab1252 100644 (file)
@@ -129,10 +129,11 @@ retry:
                ev := &events[i]
 
                if isWakeup(ev) {
-                       if delay != 0 {
+                       isBlocking := delay != 0
+                       processWakeupEvent(kq, isBlocking)
+                       if isBlocking {
                                // netpollBreak could be picked up by a nonblocking poll.
-                               // Only call drainWakeupEvent and reset the netpollWakeSig if blocking.
-                               drainWakeupEvent(kq)
+                               // Only reset the netpollWakeSig if blocking.
                                netpollWakeSig.Store(0)
                        }
                        continue
index d5f783e607e8469a45a399965e7daa65b34196f3..852a00a5d86fa49440973123efeb58e2505028fa 100644 (file)
@@ -16,7 +16,7 @@ func addWakeupEvent(kq int32) {
        ev := keventt{
                ident:  kqIdent,
                filter: _EVFILT_USER,
-               flags:  _EV_ADD,
+               flags:  _EV_ADD | _EV_CLEAR,
        }
        for {
                n := kevent(kq, &ev, 1, nil, 0, nil)
@@ -38,7 +38,6 @@ func wakeNetpoll(kq int32) {
        ev := keventt{
                ident:  kqIdent,
                filter: _EVFILT_USER,
-               flags:  _EV_ENABLE,
                fflags: _NOTE_TRIGGER,
        }
        for {
@@ -66,13 +65,11 @@ func isWakeup(ev *keventt) bool {
        return false
 }
 
-func drainWakeupEvent(kq int32) {
-       ev := keventt{
-               ident:  kqIdent,
-               filter: _EVFILT_USER,
-               flags:  _EV_DISABLE,
+func processWakeupEvent(kq int32, isBlocking bool) {
+       if !isBlocking {
+               // Got a wrong thread, relay
+               wakeNetpoll(kq)
        }
-       kevent(kq, &ev, 1, nil, 0, nil)
 }
 
 func netpollIsPollDescriptor(fd uintptr) bool {
index 98f73e84d29fc9e514ed685b0e6a37b25009d40a..cf1e2afa8371d4d6d4d4e0b41edbee0087b4d6f2 100644 (file)
@@ -63,7 +63,11 @@ func isWakeup(ev *keventt) bool {
        return false
 }
 
-func drainWakeupEvent(_ int32) {
+func processWakeupEvent(_ int32, isBlocking bool) {
+       // Only drain if blocking.
+       if !isBlocking {
+               return
+       }
        var buf [16]byte
        read(int32(netpollBreakRd), noescape(unsafe.Pointer(&buf[0])), int32(len(buf)))
 }