1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
12 "github.com/sirupsen/logrus"
15 type bufferPool struct {
16 log logrus.FieldLogger
17 // limiter has a "true" placeholder for each in-use buffer.
19 // allocated is the number of bytes currently allocated to buffers.
21 // Pool has unused buffers.
25 func newBufferPool(log logrus.FieldLogger, count int, bufSize int) *bufferPool {
26 p := bufferPool{log: log}
27 p.Pool.New = func() interface{} {
28 atomic.AddUint64(&p.allocated, uint64(bufSize))
29 return make([]byte, bufSize)
31 p.limiter = make(chan bool, count)
35 func (p *bufferPool) Get(size int) []byte {
37 case p.limiter <- true:
40 p.log.Printf("reached max buffers (%d), waiting", cap(p.limiter))
42 p.log.Printf("waited %v for a buffer", time.Since(t0))
44 buf := p.Pool.Get().([]byte)
46 p.log.Fatalf("bufferPool Get(size=%d) but max=%d", size, cap(buf))
51 func (p *bufferPool) Put(buf []byte) {
56 // Alloc returns the number of bytes allocated to buffers.
57 func (p *bufferPool) Alloc() uint64 {
58 return atomic.LoadUint64(&p.allocated)
61 // Cap returns the maximum number of buffers allowed.
62 func (p *bufferPool) Cap() int {
66 // Len returns the number of buffers in use right now.
67 func (p *bufferPool) Len() int {