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