Source: Go Sync Pool
Temporarily holding space for reusing objects instead of allocating new ones
Save on GC
Store pointer to the object, not the object (avoid allocation)
P: local processors M: machine threads G: goroutines
1 P can only have 1 M G requires a M
n number of P, can run n G parallel (if at least M available) 1 G per P
sync.Pool
is not a singleton but local pools tied to a P
P checks local pool first
shared pool chain
1type poolLocalInternal struct {
2 private any // only accesible to the P that owns it
3 shared poolChain // double linked list
4}
5
6type poolLocal struct {
7 poolLocalInternal
8 pad [128 - unsafe.Sizeof(poolLocalInternal{})%128]byte
9}
cpu cache is divided into lines pad is to keep the poolLocal in its own cache line
poolChain double linked list of poolDequeue
P that owns P-local pool, only adds to the most recent pool dequeue (head) (no locking needed)
other Ps take from the tail. Multiple consumers might try pop, atomic operations is used to keep order
when a tail dequeue is emptied, its removed
when the head is emptied, it waits to refill