Source file
src/runtime/mfixalloc.go
1
2
3
4
5
6
7
8
9 package runtime
10
11 import "unsafe"
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 type fixalloc struct {
28 size uintptr
29 first func(arg, p unsafe.Pointer)
30 arg unsafe.Pointer
31 list *mlink
32 chunk uintptr
33 nchunk uint32
34 nalloc uint32
35 inuse uintptr
36 stat *sysMemStat
37 zero bool
38 }
39
40
41
42
43
44
45
46
47 type mlink struct {
48 next *mlink
49 }
50
51
52
53 func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *sysMemStat) {
54 if size > _FixAllocChunk {
55 throw("runtime: fixalloc size too large")
56 }
57 if min := unsafe.Sizeof(mlink{}); size < min {
58 size = min
59 }
60
61 f.size = size
62 f.first = first
63 f.arg = arg
64 f.list = nil
65 f.chunk = 0
66 f.nchunk = 0
67 f.nalloc = uint32(_FixAllocChunk / size * size)
68 f.inuse = 0
69 f.stat = stat
70 f.zero = true
71 }
72
73 func (f *fixalloc) alloc() unsafe.Pointer {
74 if f.size == 0 {
75 print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
76 throw("runtime: internal error")
77 }
78
79 if f.list != nil {
80 v := unsafe.Pointer(f.list)
81 f.list = f.list.next
82 f.inuse += f.size
83 if f.zero {
84 memclrNoHeapPointers(v, f.size)
85 }
86 return v
87 }
88 if uintptr(f.nchunk) < f.size {
89 f.chunk = uintptr(persistentalloc(uintptr(f.nalloc), 0, f.stat))
90 f.nchunk = f.nalloc
91 }
92
93 v := unsafe.Pointer(f.chunk)
94 if f.first != nil {
95 f.first(f.arg, v)
96 }
97 f.chunk = f.chunk + f.size
98 f.nchunk -= uint32(f.size)
99 f.inuse += f.size
100 return v
101 }
102
103 func (f *fixalloc) free(p unsafe.Pointer) {
104 f.inuse -= f.size
105 v := (*mlink)(p)
106 v.next = f.list
107 f.list = v
108 }
109
View as plain text