]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/mgc0.go
[dev.cc] all: merge default (e4ab8f908aac) into dev.cc
[gostls13.git] / src / runtime / mgc0.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package runtime
6
7 import "unsafe"
8
9 // Called from C. Returns the Go type *m.
10 func gc_m_ptr(ret *interface{}) {
11         *ret = (*m)(nil)
12 }
13
14 // Called from C. Returns the Go type *g.
15 func gc_g_ptr(ret *interface{}) {
16         *ret = (*g)(nil)
17 }
18
19 // Called from C. Returns the Go type *itab.
20 func gc_itab_ptr(ret *interface{}) {
21         *ret = (*itab)(nil)
22 }
23
24 func gc_unixnanotime(now *int64) {
25         sec, nsec := timenow()
26         *now = sec*1e9 + int64(nsec)
27 }
28
29 func freeOSMemory() {
30         gogc(2) // force GC and do eager sweep
31         systemstack(scavenge_m)
32 }
33
34 var poolcleanup func()
35
36 func registerPoolCleanup(f func()) {
37         poolcleanup = f
38 }
39
40 func clearpools() {
41         // clear sync.Pools
42         if poolcleanup != nil {
43                 poolcleanup()
44         }
45
46         for _, p := range &allp {
47                 if p == nil {
48                         break
49                 }
50                 // clear tinyalloc pool
51                 if c := p.mcache; c != nil {
52                         c.tiny = nil
53                         c.tinysize = 0
54
55                         // disconnect cached list before dropping it on the floor,
56                         // so that a dangling ref to one entry does not pin all of them.
57                         var sg, sgnext *sudog
58                         for sg = c.sudogcache; sg != nil; sg = sgnext {
59                                 sgnext = sg.next
60                                 sg.next = nil
61                         }
62                         c.sudogcache = nil
63                 }
64
65                 // clear defer pools
66                 for i := range p.deferpool {
67                         // disconnect cached list before dropping it on the floor,
68                         // so that a dangling ref to one entry does not pin all of them.
69                         var d, dlink *_defer
70                         for d = p.deferpool[i]; d != nil; d = dlink {
71                                 dlink = d.link
72                                 d.link = nil
73                         }
74                         p.deferpool[i] = nil
75                 }
76         }
77 }
78
79 func bgsweep() {
80         sweep.g = getg()
81         getg().issystem = true
82         for {
83                 for gosweepone() != ^uintptr(0) {
84                         sweep.nbgsweep++
85                         Gosched()
86                 }
87                 lock(&gclock)
88                 if !gosweepdone() {
89                         // This can happen if a GC runs between
90                         // gosweepone returning ^0 above
91                         // and the lock being acquired.
92                         unlock(&gclock)
93                         continue
94                 }
95                 sweep.parked = true
96                 goparkunlock(&gclock, "GC sweep wait")
97         }
98 }
99
100 // NOTE: Really dst *unsafe.Pointer, src unsafe.Pointer,
101 // but if we do that, Go inserts a write barrier on *dst = src.
102 //go:nosplit
103 func writebarrierptr(dst *uintptr, src uintptr) {
104         *dst = src
105 }
106
107 //go:nosplit
108 func writebarrierstring(dst *[2]uintptr, src [2]uintptr) {
109         dst[0] = src[0]
110         dst[1] = src[1]
111 }
112
113 //go:nosplit
114 func writebarrierslice(dst *[3]uintptr, src [3]uintptr) {
115         dst[0] = src[0]
116         dst[1] = src[1]
117         dst[2] = src[2]
118 }
119
120 //go:nosplit
121 func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
122         dst[0] = src[0]
123         dst[1] = src[1]
124 }
125
126 //go:nosplit
127 func writebarrierfat2(dst *[2]uintptr, _ *byte, src [2]uintptr) {
128         dst[0] = src[0]
129         dst[1] = src[1]
130 }
131
132 //go:nosplit
133 func writebarrierfat3(dst *[3]uintptr, _ *byte, src [3]uintptr) {
134         dst[0] = src[0]
135         dst[1] = src[1]
136         dst[2] = src[2]
137 }
138
139 //go:nosplit
140 func writebarrierfat4(dst *[4]uintptr, _ *byte, src [4]uintptr) {
141         dst[0] = src[0]
142         dst[1] = src[1]
143         dst[2] = src[2]
144         dst[3] = src[3]
145 }
146
147 //go:nosplit
148 func writebarrierfat(typ *_type, dst, src unsafe.Pointer) {
149         memmove(dst, src, typ.size)
150 }