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,8 +1237,15 @@ top: ...@@ -1237,8 +1237,15 @@ top:
} }
} }
// poll network - returns list of goroutines // 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 if gp := netpoll(false); gp != nil { // non-blocking
// netpoll returns list of goroutines linked by schedlink.
injectglist(gp.schedlink) injectglist(gp.schedlink)
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
...@@ -1246,6 +1253,7 @@ top: ...@@ -1246,6 +1253,7 @@ top:
} }
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.
// This is necessary to prevent excessive CPU consumption // This is necessary to prevent excessive CPU consumption
......
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