aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/runtime/proc.go23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index f4af26f172..68d20edf41 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -84,7 +84,7 @@ var modinfo string
// semi-persistent CPU underutilization.
//
// The general pattern for submission is:
-// 1. Submit work to the local run queue, timer heap, or GC state.
+// 1. Submit work to the local or global run queue, timer heap, or GC state.
// 2. #StoreLoad-style memory barrier.
// 3. Check sched.nmspinning.
//
@@ -3093,7 +3093,7 @@ top:
//
// This applies to the following sources of work:
//
- // * Goroutines added to a per-P run queue.
+ // * Goroutines added to the global or a per-P run queue.
// * New/modified-earlier timers on a per-P timer heap.
// * Idle-priority GC work (barring golang.org/issue/19112).
//
@@ -3135,7 +3135,24 @@ top:
//
// See https://go.dev/issue/43997.
- // Check all runqueues once again.
+ // Check global and P runqueues again.
+
+ lock(&sched.lock)
+ if sched.runqsize != 0 {
+ pp, _ := pidlegetSpinning(0)
+ if pp != nil {
+ gp := globrunqget(pp, 0)
+ if gp == nil {
+ throw("global runq empty with non-zero runqsize")
+ }
+ unlock(&sched.lock)
+ acquirep(pp)
+ mp.becomeSpinning()
+ return gp, false, false
+ }
+ }
+ unlock(&sched.lock)
+
pp := checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
if pp != nil {
acquirep(pp)