mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: bound defer pools (try 2)
The unbounded list-based defer pool can grow infinitely. This can happen if a goroutine routinely allocates a defer; then blocks on one P; and then unblocked, scheduled and frees the defer on another P. The scenario was reported on golang-nuts list. We've been here several times. Any unbounded local caches are bad and grow to infinite size. This change introduces central defer pool; local pools become fixed-size with the only purpose of amortizing accesses to the central pool. Freedefer now executes on system stack to not consume nosplit stack space. Change-Id: I1a27695838409259d1586a0adfa9f92bccf7ceba Reviewed-on: https://go-review.googlesource.com/3967 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
This commit is contained in:
parent
5ef145c809
commit
b759e225f5
4 changed files with 70 additions and 20 deletions
|
|
@ -314,7 +314,9 @@ type p struct {
|
|||
syscalltick uint32 // incremented on every system call
|
||||
m *m // back-link to associated m (nil if idle)
|
||||
mcache *mcache
|
||||
deferpool [5]*_defer // pool of available defer structs of different sizes (see panic.c)
|
||||
|
||||
deferpool [5][]*_defer // pool of available defer structs of different sizes (see panic.c)
|
||||
deferpoolbuf [5][32]*_defer
|
||||
|
||||
// Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
|
||||
goidcache uint64
|
||||
|
|
@ -372,6 +374,10 @@ type schedt struct {
|
|||
sudoglock mutex
|
||||
sudogcache *sudog
|
||||
|
||||
// Central pool of available defer structs of different sizes.
|
||||
deferlock mutex
|
||||
deferpool [5]*_defer
|
||||
|
||||
gcwaiting uint32 // gc is waiting to run
|
||||
stopwait int32
|
||||
stopnote note
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue