mirror of
https://github.com/golang/go.git
synced 2025-05-30 19:52:53 +00:00
runtime: split gfree list into with-stacks and without-stacks
Currently all free Gs are added to one list. Split this into two lists: one for free Gs with cached stacks and one for Gs without cached stacks. This lets us preferentially allocate Gs that already have a stack, but more importantly, it sets us up to free cached G stacks concurrently. Change-Id: Idbe486f708997e1c9d166662995283f02d1eeb3c Reviewed-on: https://go-review.googlesource.com/20664 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
3b0efa689e
commit
1a2cf91f5e
@ -2798,8 +2798,13 @@ func gfput(_p_ *p, gp *g) {
|
|||||||
_p_.gfreecnt--
|
_p_.gfreecnt--
|
||||||
gp = _p_.gfree
|
gp = _p_.gfree
|
||||||
_p_.gfree = gp.schedlink.ptr()
|
_p_.gfree = gp.schedlink.ptr()
|
||||||
gp.schedlink.set(sched.gfree)
|
if gp.stack.lo == 0 {
|
||||||
sched.gfree = gp
|
gp.schedlink.set(sched.gfreeNoStack)
|
||||||
|
sched.gfreeNoStack = gp
|
||||||
|
} else {
|
||||||
|
gp.schedlink.set(sched.gfreeStack)
|
||||||
|
sched.gfreeStack = gp
|
||||||
|
}
|
||||||
sched.ngfree++
|
sched.ngfree++
|
||||||
}
|
}
|
||||||
unlock(&sched.gflock)
|
unlock(&sched.gflock)
|
||||||
@ -2811,12 +2816,20 @@ func gfput(_p_ *p, gp *g) {
|
|||||||
func gfget(_p_ *p) *g {
|
func gfget(_p_ *p) *g {
|
||||||
retry:
|
retry:
|
||||||
gp := _p_.gfree
|
gp := _p_.gfree
|
||||||
if gp == nil && sched.gfree != nil {
|
if gp == nil && (sched.gfreeStack != nil || sched.gfreeNoStack != nil) {
|
||||||
lock(&sched.gflock)
|
lock(&sched.gflock)
|
||||||
for _p_.gfreecnt < 32 && sched.gfree != nil {
|
for _p_.gfreecnt < 32 {
|
||||||
|
if sched.gfreeStack != nil {
|
||||||
|
// Prefer Gs with stacks.
|
||||||
|
gp = sched.gfreeStack
|
||||||
|
sched.gfreeStack = gp.schedlink.ptr()
|
||||||
|
} else if sched.gfreeNoStack != nil {
|
||||||
|
gp = sched.gfreeNoStack
|
||||||
|
sched.gfreeNoStack = gp.schedlink.ptr()
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
_p_.gfreecnt++
|
_p_.gfreecnt++
|
||||||
gp = sched.gfree
|
|
||||||
sched.gfree = gp.schedlink.ptr()
|
|
||||||
sched.ngfree--
|
sched.ngfree--
|
||||||
gp.schedlink.set(_p_.gfree)
|
gp.schedlink.set(_p_.gfree)
|
||||||
_p_.gfree = gp
|
_p_.gfree = gp
|
||||||
@ -2853,8 +2866,13 @@ func gfpurge(_p_ *p) {
|
|||||||
_p_.gfreecnt--
|
_p_.gfreecnt--
|
||||||
gp := _p_.gfree
|
gp := _p_.gfree
|
||||||
_p_.gfree = gp.schedlink.ptr()
|
_p_.gfree = gp.schedlink.ptr()
|
||||||
gp.schedlink.set(sched.gfree)
|
if gp.stack.lo == 0 {
|
||||||
sched.gfree = gp
|
gp.schedlink.set(sched.gfreeNoStack)
|
||||||
|
sched.gfreeNoStack = gp
|
||||||
|
} else {
|
||||||
|
gp.schedlink.set(sched.gfreeStack)
|
||||||
|
sched.gfreeStack = gp
|
||||||
|
}
|
||||||
sched.ngfree++
|
sched.ngfree++
|
||||||
}
|
}
|
||||||
unlock(&sched.gflock)
|
unlock(&sched.gflock)
|
||||||
|
@ -523,9 +523,10 @@ type schedt struct {
|
|||||||
runqsize int32
|
runqsize int32
|
||||||
|
|
||||||
// Global cache of dead G's.
|
// Global cache of dead G's.
|
||||||
gflock mutex
|
gflock mutex
|
||||||
gfree *g
|
gfreeStack *g
|
||||||
ngfree int32
|
gfreeNoStack *g
|
||||||
|
ngfree int32
|
||||||
|
|
||||||
// Central cache of sudog structs.
|
// Central cache of sudog structs.
|
||||||
sudoglock mutex
|
sudoglock mutex
|
||||||
|
Loading…
x
Reference in New Issue
Block a user