Skip to content

Commit

Permalink
util/log: use sync.Pool for formatting buffer
Browse files Browse the repository at this point in the history
This was suggested by @petermattis: the free list code predates the
introduction of `sync.Pool` in the Go standard library. Using
`sync.Pool` ensures that the code becomes less sensitive to a missing
call to `putBuffer()`.

Release note: None
  • Loading branch information
knz committed Oct 14, 2019
1 parent d1c8c39 commit 56e5ad2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 33 deletions.
11 changes: 4 additions & 7 deletions pkg/util/log/clog.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"fmt"
"os"
"runtime/debug"
"sync"
"sync/atomic"
"time"

Expand All @@ -38,13 +39,8 @@ type loggingT struct {
// Level flag for output to stderr. Handled atomically.
stderrThreshold Severity

freeList struct {
syncutil.Mutex

// head is a list of byte buffers, maintained under
// freeList.Lock().
head *buffer
}
// pool for entry formatting buffers.
bufPool sync.Pool

// interceptor is the configured InterceptorFn callback, if any.
interceptor atomic.Value
Expand Down Expand Up @@ -113,6 +109,7 @@ type loggerT struct {
}

func init() {
logging.bufPool.New = newBuffer
logging.mu.fatalCh = make(chan struct{})
// Default stderrThreshold and fileThreshold to log everything.
// This will be the default in tests unless overridden; the CLI
Expand Down
32 changes: 6 additions & 26 deletions pkg/util/log/log_buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@

package log

import (
"bytes"

"github.com/knz/shakespeare/pkg/crdb/syncutil"
)
import "bytes"

// buffer holds a byte Buffer for reuse while constructing log lines
// prior to sending them to a sync buffer or log stream.
Expand All @@ -26,26 +22,13 @@ type buffer struct {
next *buffer
}

var freeList struct {
syncutil.Mutex
// head is the head of a list of byte buffers, maintained under the mutex.
head *buffer
}
// newBuffer is the constructor for the sync.Pool.
func newBuffer() interface{} { return new(buffer) }

// getBuffer returns a new, ready-to-use buffer.
func getBuffer() *buffer {
freeList.Lock()
b := freeList.head
if b != nil {
freeList.head = b.next
}
freeList.Unlock()
if b == nil {
b = new(buffer)
} else {
b.next = nil
b.Reset()
}
b := logging.bufPool.Get().(*buffer)
b.Reset()
return b
}

Expand All @@ -55,10 +38,7 @@ func putBuffer(b *buffer) {
// Let big buffers die a natural death.
return
}
freeList.Lock()
b.next = freeList.head
freeList.head = b
freeList.Unlock()
logging.bufPool.Put(b)
}

// Some custom tiny helper functions to print the log header efficiently.
Expand Down

0 comments on commit 56e5ad2

Please sign in to comment.