From a8787cd820fb39575efed14617dde2fb8131b354 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Thu, 10 Apr 2014 05:45:18 +1000 Subject: [PATCH] sync.Pool: better documentation Explain what its purpose is and give examples of good and bad use. Fixes #7167. LGTM=dvyukov, rsc R=golang-codereviews, dvyukov, rsc CC=golang-codereviews https://golang.org/cl/85880044 --- src/pkg/sync/pool.go | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/pkg/sync/pool.go b/src/pkg/sync/pool.go index ca49d21a0d..a078cdc920 100644 --- a/src/pkg/sync/pool.go +++ b/src/pkg/sync/pool.go @@ -16,27 +16,35 @@ const ( poolLocalCap = poolLocalSize/unsafe.Sizeof(*(*interface{})(nil)) - 1 ) -// A Pool is a set of temporary objects that may be individually saved -// and retrieved. +// A Pool is a set of temporary objects that may be individually saved and +// retrieved. // -// Any item stored in the Pool may be removed automatically by the -// implementation at any time without notification. -// If the Pool holds the only reference when this happens, the item -// might be deallocated. +// Any item stored in the Pool may be removed automatically at any time without +// notification. If the Pool holds the only reference when this happens, the +// item might be deallocated. // // A Pool is safe for use by multiple goroutines simultaneously. // -// Pool's intended use is for free lists maintained in global variables, -// typically accessed by multiple goroutines simultaneously. Using a -// Pool instead of a custom free list allows the runtime to reclaim -// entries from the pool when it makes sense to do so. An -// appropriate use of sync.Pool is to create a pool of temporary buffers -// shared between independent clients of a global resource. On the -// other hand, if a free list is maintained as part of an object used -// only by a single client and freed when the client completes, -// implementing that free list as a Pool is not appropriate. +// Pool's purpose is to cache allocated but unused items for later reuse, +// relieving pressure on the garbage collector. That is, it makes it easy to +// build efficient, thread-safe free lists. However, it is not suitable for all +// free lists. +// +// An appropriate use of a Pool is to manage a group of temporary items +// silently shared among and potentially reused by concurrent independent +// clients of a package. Pool provides a way to amortize allocation overhead +// across many clients. +// +// An example of good use of a Pool is in the fmt package, which maintains a +// dynamically-sized store of temporary output buffers. The store scales under +// load (when many goroutines are actively printing) and shrinks when +// quiescent. +// +// On the other hand, a free list maintained as part of a short-lived object is +// not a suitable use for a Pool, since the overhead does not amortize well in +// that scenario. It is more efficient to have such objects implement their own +// free list. // -// This is an experimental type and might not be released. type Pool struct { // The following fields are known to runtime. next *Pool // for use by runtime @@ -173,7 +181,7 @@ func (p *Pool) getSlow() (x interface{}) { return } -// pin pins current goroutine to P, disables preemption and returns poolLocal pool for the P. +// pin pins the current goroutine to P, disables preemption and returns poolLocal pool for the P. // Caller must call runtime_procUnpin() when done with the pool. func (p *Pool) pin() *poolLocal { pid := runtime_procPin() -- 2.50.0