Commit f47e581e authored by Dmitry Vyukov's avatar Dmitry Vyukov

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/4553Reviewed-by: 's avatarKeith Randall <khr@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
parent 3c8a89da
...@@ -1237,14 +1237,22 @@ top: ...@@ -1237,14 +1237,22 @@ top:
} }
} }
// poll network - returns list of goroutines // Poll network.
if gp := netpoll(false); gp != nil { // non-blocking // This netpoll is only an optimization before we resort to stealing.
injectglist(gp.schedlink) // We can safely skip it if there a thread blocked in netpoll already.
casgstatus(gp, _Gwaiting, _Grunnable) // If there is any kind of logical race with that blocked thread
if trace.enabled { // (e.g. it has already returned from netpoll, but does not set lastpoll yet),
traceGoUnpark(gp) // 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. // If number of spinning M's >= number of busy P's, block.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment