LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Cgo call and callback support. | 5 // Cgo call and callback support. |
6 // | 6 // |
7 // To call into the C function f from Go, the cgo-generated code calls | 7 // To call into the C function f from Go, the cgo-generated code calls |
8 // runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a | 8 // runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a |
9 // gcc-compiled function written by cgo. | 9 // gcc-compiled function written by cgo. |
10 // | 10 // |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 return args.ret | 170 return args.ret |
171 } | 171 } |
172 | 172 |
173 func cfree(p unsafe.Pointer) { | 173 func cfree(p unsafe.Pointer) { |
174 cgocall(cgoFree, p) | 174 cgocall(cgoFree, p) |
175 } | 175 } |
176 | 176 |
177 // Call from C back to Go. | 177 // Call from C back to Go. |
178 //go:nosplit | 178 //go:nosplit |
179 func cgocallbackg() { | 179 func cgocallbackg() { |
180 » if gp := getg(); gp != gp.m.curg { | 180 » gp := getg() |
| 181 » if gp != gp.m.curg { |
181 println("runtime: bad g in cgocallback") | 182 println("runtime: bad g in cgocallback") |
182 exit(2) | 183 exit(2) |
183 } | 184 } |
184 | 185 |
| 186 // entersyscall saves the caller's SP to allow the GC to trace the Go |
| 187 // stack. However, since we're returning to an earlier stack frame and |
| 188 // need to pair with the entersyscall() call made by cgocall, we must |
| 189 // save syscall* and let reentersyscall restore them. |
| 190 savedsp := unsafe.Pointer(gp.syscallsp) |
| 191 savedpc := gp.syscallpc |
185 exitsyscall() // coming out of cgo call | 192 exitsyscall() // coming out of cgo call |
186 cgocallbackg1() | 193 cgocallbackg1() |
187 » entersyscall() // going back to cgo call | 194 » // going back to cgo call |
| 195 » reentersyscall(savedpc, savedsp) |
188 } | 196 } |
189 | 197 |
190 func cgocallbackg1() { | 198 func cgocallbackg1() { |
191 gp := getg() | 199 gp := getg() |
192 if gp.m.needextram { | 200 if gp.m.needextram { |
193 gp.m.needextram = false | 201 gp.m.needextram = false |
194 onM(newextram) | 202 onM(newextram) |
195 } | 203 } |
196 | 204 |
197 // Add entry to defer stack in case of panic. | 205 // Add entry to defer stack in case of panic. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
262 func badcgocallback() { | 270 func badcgocallback() { |
263 gothrow("misaligned stack in cgocallback") | 271 gothrow("misaligned stack in cgocallback") |
264 } | 272 } |
265 | 273 |
266 // called from (incomplete) assembly | 274 // called from (incomplete) assembly |
267 func cgounimpl() { | 275 func cgounimpl() { |
268 gothrow("cgo not implemented") | 276 gothrow("cgo not implemented") |
269 } | 277 } |
270 | 278 |
271 var racecgosync uint64 // represents possible synchronization in C code | 279 var racecgosync uint64 // represents possible synchronization in C code |
LEFT | RIGHT |