forked from CodisLabs/codis
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cgo_slice.go
75 lines (62 loc) · 1.35 KB
/
cgo_slice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2016 CodisLabs. All Rights Reserved.
// Licensed under the MIT (MIT-LICENSE.txt) license.
package unsafe2
import (
"reflect"
"runtime"
"unsafe"
"github.com/CodisLabs/codis/pkg/utils/sync2/atomic2"
)
var allocOffheapBytes atomic2.Int64
func OffheapBytes() int64 {
return allocOffheapBytes.Int64()
}
type cgoSlice struct {
ptr unsafe.Pointer
buf []byte
}
func newCGoSlice(n int, force bool) Slice {
after := allocOffheapBytes.Add(int64(n))
if !force && after > MaxOffheapBytes() {
allocOffheapBytes.Sub(int64(n))
return nil
}
p := cgo_malloc(n)
if p == nil {
allocOffheapBytes.Sub(int64(n))
return nil
}
s := &cgoSlice{
ptr: p,
buf: *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(p), Len: n, Cap: n,
})),
}
runtime.SetFinalizer(s, (*cgoSlice).reclaim)
return s
}
func (s *cgoSlice) Type() string {
return "cgo_slice"
}
func (s *cgoSlice) Buffer() []byte {
return s.buf
}
func (s *cgoSlice) reclaim() {
if s.ptr == nil {
return
}
cgo_free(s.ptr)
allocOffheapBytes.Sub(int64(len(s.buf)))
s.ptr = nil
s.buf = nil
runtime.SetFinalizer(s, nil)
}
func (s *cgoSlice) Slice2(beg, end int) Slice {
return newGoSliceFrom(s, s.Buffer()[beg:end])
}
func (s *cgoSlice) Slice3(beg, end, cap int) Slice {
return newGoSliceFrom(s, s.Buffer()[beg:end:cap])
}
func (s *cgoSlice) Parent() Slice {
return nil
}