mirror of https://github.com/golang/go.git
runtime: do not do futile netpolls
There is no sense in trying to netpoll while there is already a thread blocked in netpoll. And in most cases there must be a thread blocked in netpoll, because the first otherwise idle thread does blocking netpoll. On some program I see that netpoll called from findrunnable consumes 3% of time. Change-Id: I0af1a73d637bffd9770ea50cb9278839716e8816 Reviewed-on: https://go-review.googlesource.com/4553 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
3c8a89daf3
commit
f47e581e02
|
|
@ -1237,14 +1237,22 @@ top:
|
|||
}
|
||||
}
|
||||
|
||||
// poll network - returns list of goroutines
|
||||
if gp := netpoll(false); gp != nil { // non-blocking
|
||||
injectglist(gp.schedlink)
|
||||
casgstatus(gp, _Gwaiting, _Grunnable)
|
||||
if trace.enabled {
|
||||
traceGoUnpark(gp)
|
||||
// Poll network.
|
||||
// This netpoll is only an optimization before we resort to stealing.
|
||||
// We can safely skip it if there a thread blocked in netpoll already.
|
||||
// If there is any kind of logical race with that blocked thread
|
||||
// (e.g. it has already returned from netpoll, but does not set lastpoll yet),
|
||||
// this thread will do blocking netpoll below anyway.
|
||||
if netpollinited() && sched.lastpoll != 0 {
|
||||
if gp := netpoll(false); gp != nil { // non-blocking
|
||||
// netpoll returns list of goroutines linked by schedlink.
|
||||
injectglist(gp.schedlink)
|
||||
casgstatus(gp, _Gwaiting, _Grunnable)
|
||||
if trace.enabled {
|
||||
traceGoUnpark(gp)
|
||||
}
|
||||
return gp
|
||||
}
|
||||
return gp
|
||||
}
|
||||
|
||||
// If number of spinning M's >= number of busy P's, block.
|
||||
|
|
|
|||
Loading…
Reference in New Issue