Commit 83ba0346 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Plug memory leak in bufferpool code: reused buffers should also be in

the handed-out table.
parent 2b9f0042
......@@ -4,8 +4,11 @@ import (
"sync"
"fmt"
"unsafe"
"log"
)
var _ = log.Println
// This implements a pool of buffers that returns slices with capacity
// (2^e * PAGESIZE) for e=0,1,... which have possibly been used, and
// may contain random contents.
......@@ -17,6 +20,10 @@ type BufferPool struct {
// start of slice -> exponent.
outstandingBuffers map[uintptr]uint
// Total count of created buffers. Handy for finding memory
// leaks.
createdBuffers int
}
// Returns the smallest E such that 2^E >= Z.
......@@ -71,6 +78,13 @@ func (me *BufferPool) addBuffer(slice []byte, exp uint) {
}
func (me *BufferPool) AllocCount() int {
me.lock.Lock()
defer me.lock.Unlock()
return me.createdBuffers
}
func (me *BufferPool) AllocBuffer(size uint32) []byte {
sz := int(size)
if sz < PAGESIZE {
......@@ -87,12 +101,13 @@ func (me *BufferPool) AllocBuffer(size uint32) []byte {
b := me.getBuffer(exp)
if b != nil {
if b == nil {
me.createdBuffers++
b = make([]byte, size, rounded)
} else {
b = b[:size]
return b
}
b = make([]byte, size, rounded)
me.outstandingBuffers[uintptr(unsafe.Pointer(&b[0]))] = exp
return b
}
......@@ -103,9 +118,9 @@ func (me *BufferPool) FreeBuffer(slice []byte) {
if cap(slice) < PAGESIZE {
return
}
slice = slice[:cap(slice)]
slice = slice[:cap(slice)]
key := uintptr(unsafe.Pointer(&slice[0]))
me.lock.Lock()
defer me.lock.Unlock()
exp, ok := me.outstandingBuffers[key]
......
......@@ -3,7 +3,6 @@ package fuse
import (
"bytes"
"encoding/binary"
"expvar"
"fmt"
"log"
"os"
......@@ -240,18 +239,8 @@ func (me *MountState) OperationCounts() map[string]int64 {
}
func (me *MountState) Stats() string {
var lines []string
// TODO - bufferpool should use expvar.
lines = append(lines,
fmt.Sprintf("buffers: %v", me.buffers.String()))
for v := range expvar.Iter() {
if strings.HasPrefix(v.Key, "mount") {
lines = append(lines, fmt.Sprintf("%v: %v\n", v.Key, v.Value))
}
}
return strings.Join(lines, "\n")
return fmt.Sprintf("buffer alloc count %d\nbuffers %v",
me.buffers.AllocCount(), me.buffers.String())
}
////////////////////////////////////////////////////////////////
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment