1 // Copyright 2016 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.
8 "runtime/internal/atomic"
12 // For historical reasons these functions are called as though they
13 // were in the syscall package.
14 //go:linkname Cgocall syscall.Cgocall
15 //go:linkname CgocallDone syscall.CgocallDone
16 //go:linkname CgocallBack syscall.CgocallBack
17 //go:linkname CgocallBackDone syscall.CgocallBackDone
19 // A routine that may be called by SWIG.
20 //go:linkname _cgo_panic _cgo_panic
22 // iscgo is set to true if the cgo tool sets the C variable runtime_iscgo
26 // cgoHasExtraM is set on startup when an extra M is created for cgo.
27 // The extra M must be created before any C/C++ code calls cgocallback.
30 // Cgocall prepares to call from code written in Go to code written in
31 // C/C++. This takes the current goroutine out of the Go scheduler, as
32 // though it were making a system call. Otherwise the program can
33 // lookup if the C code blocks. The idea is to call this function,
34 // then immediately call the C/C++ function. After the C/C++ function
35 // returns, call cgocalldone. The usual Go code would look like
37 // defer syscall.Cgocalldone()
47 // CgocallDone prepares to return to Go code from C/C++ code.
51 throw("no g in CgocallDone")
55 // If we are invoked because the C function called _cgo_panic,
56 // then _cgo_panic will already have exited syscall mode.
57 if gp
.atomicstatus
== _Gsyscall
{
64 // CgocallBack is used when calling from C/C++ code into Go code.
65 // The usual approach is
66 // syscall.CgocallBack()
67 // defer syscall.CgocallBackDone()
71 if getg() == nil ||
getg().m
== nil {
79 if getg().m
.ncgo
== 0 {
80 // The C call to Go came from a thread created by C.
81 // The C call to Go came from a thread not currently running
82 // any Go. In the case of -buildmode=c-archive or c-shared,
83 // this call may be coming in before package initialization
84 // is complete. Wait until it is.
89 if mp
.needextram || atomic
.Load(&extraMWaiters
) > 0 {
95 // CgocallBackDone prepares to return to C/C++ code that has called
97 func CgocallBackDone() {
100 if mp
.dropextram
&& mp
.ncgo
== 0 {
101 mp
.dropextram
= false
106 // _cgo_panic may be called by SWIG code to panic.
107 func _cgo_panic(p
*byte) {
109 panic(gostringnocopy(p
))