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:
parent
bedde1bee0
commit
e707d47326
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user