53
vendor/github.com/VictoriaMetrics/fastcache/malloc_mmap.go
generated
vendored
Normal file
53
vendor/github.com/VictoriaMetrics/fastcache/malloc_mmap.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// +build !appengine,!windows
|
||||
|
||||
package fastcache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const chunksPerAlloc = 1024
|
||||
|
||||
var (
|
||||
freeChunks []*[chunkSize]byte
|
||||
freeChunksLock sync.Mutex
|
||||
)
|
||||
|
||||
func getChunk() []byte {
|
||||
freeChunksLock.Lock()
|
||||
if len(freeChunks) == 0 {
|
||||
// Allocate offheap memory, so GOGC won't take into account cache size.
|
||||
// This should reduce free memory waste.
|
||||
data, err := unix.Mmap(-1, 0, chunkSize*chunksPerAlloc, unix.PROT_READ|unix.PROT_WRITE, unix.MAP_ANON|unix.MAP_PRIVATE)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot allocate %d bytes via mmap: %s", chunkSize*chunksPerAlloc, err))
|
||||
}
|
||||
for len(data) > 0 {
|
||||
p := (*[chunkSize]byte)(unsafe.Pointer(&data[0]))
|
||||
freeChunks = append(freeChunks, p)
|
||||
data = data[chunkSize:]
|
||||
}
|
||||
}
|
||||
n := len(freeChunks) - 1
|
||||
p := freeChunks[n]
|
||||
freeChunks[n] = nil
|
||||
freeChunks = freeChunks[:n]
|
||||
freeChunksLock.Unlock()
|
||||
return p[:]
|
||||
}
|
||||
|
||||
func putChunk(chunk []byte) {
|
||||
if chunk == nil {
|
||||
return
|
||||
}
|
||||
chunk = chunk[:chunkSize]
|
||||
p := (*[chunkSize]byte)(unsafe.Pointer(&chunk[0]))
|
||||
|
||||
freeChunksLock.Lock()
|
||||
freeChunks = append(freeChunks, p)
|
||||
freeChunksLock.Unlock()
|
||||
}
|
||||
Reference in New Issue
Block a user