Commit 083938df authored by Austin Clements's avatar Austin Clements

runtime: use gList for injectglist

Change-Id: Id5af75eaaf41f43bc6baa6d3fe2b852a2f93bb6f
Reviewed-on: https://go-review.googlesource.com/129400
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent d02169d3
...@@ -1630,8 +1630,7 @@ func gcMarkTermination(nextTriggerRatio float64) { ...@@ -1630,8 +1630,7 @@ func gcMarkTermination(nextTriggerRatio float64) {
// Bump GC cycle count and wake goroutines waiting on sweep. // Bump GC cycle count and wake goroutines waiting on sweep.
lock(&work.sweepWaiters.lock) lock(&work.sweepWaiters.lock)
memstats.numgc++ memstats.numgc++
injectglist(work.sweepWaiters.list.head.ptr()) injectglist(&work.sweepWaiters.list)
work.sweepWaiters.list = gList{}
unlock(&work.sweepWaiters.lock) unlock(&work.sweepWaiters.lock)
// Finish the current heap profiling cycle and start a new // Finish the current heap profiling cycle and start a new
......
...@@ -603,7 +603,8 @@ func gcAssistAlloc1(gp *g, scanWork int64) { ...@@ -603,7 +603,8 @@ func gcAssistAlloc1(gp *g, scanWork int64) {
// new assists from going to sleep after this point. // new assists from going to sleep after this point.
func gcWakeAllAssists() { func gcWakeAllAssists() {
lock(&work.assistQueue.lock) lock(&work.assistQueue.lock)
injectglist(work.assistQueue.q.popList().head.ptr()) list := work.assistQueue.q.popList()
injectglist(&list)
unlock(&work.assistQueue.lock) unlock(&work.assistQueue.lock)
} }
......
...@@ -1149,7 +1149,7 @@ func startTheWorldWithSema(emitTraceEvent bool) int64 { ...@@ -1149,7 +1149,7 @@ func startTheWorldWithSema(emitTraceEvent bool) int64 {
_g_.m.locks++ // disable preemption because it can be holding p in a local var _g_.m.locks++ // disable preemption because it can be holding p in a local var
if netpollinited() { if netpollinited() {
list := netpoll(false) // non-blocking list := netpoll(false) // non-blocking
injectglist(list.head.ptr()) injectglist(&list)
} }
add := needaddgcproc() add := needaddgcproc()
lock(&sched.lock) lock(&sched.lock)
...@@ -2314,7 +2314,7 @@ top: ...@@ -2314,7 +2314,7 @@ top:
if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Load64(&sched.lastpoll) != 0 { if netpollinited() && atomic.Load(&netpollWaiters) > 0 && atomic.Load64(&sched.lastpoll) != 0 {
if list := netpoll(false); !list.empty() { // non-blocking if list := netpoll(false); !list.empty() { // non-blocking
gp := list.pop() gp := list.pop()
injectglist(list.head.ptr()) injectglist(&list)
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
traceGoUnpark(gp, 0) traceGoUnpark(gp, 0)
...@@ -2475,14 +2475,14 @@ stop: ...@@ -2475,14 +2475,14 @@ stop:
if _p_ != nil { if _p_ != nil {
acquirep(_p_) acquirep(_p_)
gp := list.pop() gp := list.pop()
injectglist(list.head.ptr()) injectglist(&list)
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
traceGoUnpark(gp, 0) traceGoUnpark(gp, 0)
} }
return gp, false return gp, false
} }
injectglist(list.head.ptr()) injectglist(&list)
} }
} }
stopm() stopm()
...@@ -2503,7 +2503,7 @@ func pollWork() bool { ...@@ -2503,7 +2503,7 @@ func pollWork() bool {
} }
if netpollinited() && atomic.Load(&netpollWaiters) > 0 && sched.lastpoll != 0 { if netpollinited() && atomic.Load(&netpollWaiters) > 0 && sched.lastpoll != 0 {
if list := netpoll(false); !list.empty() { if list := netpoll(false); !list.empty() {
injectglist(list.head.ptr()) injectglist(&list)
return true return true
} }
} }
...@@ -2528,22 +2528,21 @@ func resetspinning() { ...@@ -2528,22 +2528,21 @@ func resetspinning() {
} }
} }
// Injects the list of runnable G's into the scheduler. // Injects the list of runnable G's into the scheduler and clears glist.
// Can run concurrently with GC. // Can run concurrently with GC.
func injectglist(glist *g) { func injectglist(glist *gList) {
if glist == nil { if glist.empty() {
return return
} }
if trace.enabled { if trace.enabled {
for gp := glist; gp != nil; gp = gp.schedlink.ptr() { for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
traceGoUnpark(gp, 0) traceGoUnpark(gp, 0)
} }
} }
lock(&sched.lock) lock(&sched.lock)
var n int var n int
for n = 0; glist != nil; n++ { for n = 0; !glist.empty(); n++ {
gp := glist gp := glist.pop()
glist = gp.schedlink.ptr()
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
globrunqput(gp) globrunqput(gp)
} }
...@@ -2551,6 +2550,7 @@ func injectglist(glist *g) { ...@@ -2551,6 +2550,7 @@ func injectglist(glist *g) {
for ; n != 0 && sched.npidle != 0; n-- { for ; n != 0 && sched.npidle != 0; n-- {
startm(nil, false) startm(nil, false)
} }
*glist = gList{}
} }
// One round of scheduler: find a runnable goroutine and execute it. // One round of scheduler: find a runnable goroutine and execute it.
...@@ -4389,7 +4389,7 @@ func sysmon() { ...@@ -4389,7 +4389,7 @@ func sysmon() {
// observes that there is no work to do and no other running M's // observes that there is no work to do and no other running M's
// and reports deadlock. // and reports deadlock.
incidlelocked(-1) incidlelocked(-1)
injectglist(list.head.ptr()) injectglist(&list)
incidlelocked(1) incidlelocked(1)
} }
} }
...@@ -4404,8 +4404,9 @@ func sysmon() { ...@@ -4404,8 +4404,9 @@ func sysmon() {
if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && atomic.Load(&forcegc.idle) != 0 { if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && atomic.Load(&forcegc.idle) != 0 {
lock(&forcegc.lock) lock(&forcegc.lock)
forcegc.idle = 0 forcegc.idle = 0
forcegc.g.schedlink = 0 var list gList
injectglist(forcegc.g) list.push(forcegc.g)
injectglist(&list)
unlock(&forcegc.lock) unlock(&forcegc.lock)
} }
// scavenge heap once in a while // scavenge heap once in a while
......
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