1
0
mirror of https://github.com/golang/go synced 2024-11-24 21:10:04 -07:00

runtime: utilize EVFILT_USER more effectively

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.
This commit is contained in:
Maksym Sobolyev 2024-11-18 00:04:26 -08:00
parent bedde1bee0
commit e707d47326
3 changed files with 14 additions and 12 deletions

View File

@ -129,10 +129,11 @@ retry:
ev := &events[i] ev := &events[i]
if isWakeup(ev) { if isWakeup(ev) {
if delay != 0 { isBlocking := delay != 0
processWakeupEvent(kq, isBlocking)
if isBlocking {
// netpollBreak could be picked up by a nonblocking poll. // netpollBreak could be picked up by a nonblocking poll.
// Only call drainWakeupEvent and reset the netpollWakeSig if blocking. // Only reset the netpollWakeSig if blocking.
drainWakeupEvent(kq)
netpollWakeSig.Store(0) netpollWakeSig.Store(0)
} }
continue continue

View File

@ -16,7 +16,7 @@ func addWakeupEvent(kq int32) {
ev := keventt{ ev := keventt{
ident: kqIdent, ident: kqIdent,
filter: _EVFILT_USER, filter: _EVFILT_USER,
flags: _EV_ADD, flags: _EV_ADD | _EV_CLEAR,
} }
for { for {
n := kevent(kq, &ev, 1, nil, 0, nil) n := kevent(kq, &ev, 1, nil, 0, nil)
@ -38,7 +38,6 @@ func wakeNetpoll(kq int32) {
ev := keventt{ ev := keventt{
ident: kqIdent, ident: kqIdent,
filter: _EVFILT_USER, filter: _EVFILT_USER,
flags: _EV_ENABLE,
fflags: _NOTE_TRIGGER, fflags: _NOTE_TRIGGER,
} }
for { for {
@ -66,13 +65,11 @@ func isWakeup(ev *keventt) bool {
return false return false
} }
func drainWakeupEvent(kq int32) { func processWakeupEvent(kq int32, isBlocking bool) {
ev := keventt{ if !isBlocking {
ident: kqIdent, // Got a wrong thread, relay
filter: _EVFILT_USER, wakeNetpoll(kq)
flags: _EV_DISABLE,
} }
kevent(kq, &ev, 1, nil, 0, nil)
} }
func netpollIsPollDescriptor(fd uintptr) bool { func netpollIsPollDescriptor(fd uintptr) bool {

View File

@ -63,7 +63,11 @@ func isWakeup(ev *keventt) bool {
return false return false
} }
func drainWakeupEvent(_ int32) { func processWakeupEvent(_ int32, isBlocking bool) {
// Only drain if blocking.
if !isBlocking {
return
}
var buf [16]byte var buf [16]byte
read(int32(netpollBreakRd), noescape(unsafe.Pointer(&buf[0])), int32(len(buf))) read(int32(netpollBreakRd), noescape(unsafe.Pointer(&buf[0])), int32(len(buf)))
} }