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()
48 // CgocallDone prepares to return to Go code from C/C++ code.
52 throw("no g in CgocallDone")
57 // If we are invoked because the C function called _cgo_panic,
58 // then _cgo_panic will already have exited syscall mode.
59 if readgstatus(gp
)&^_Gscan
== _Gsyscall
{
66 // CgocallBack is used when calling from C/C++ code into Go code.
67 // The usual approach is
68 // syscall.CgocallBack()
69 // defer syscall.CgocallBackDone()
74 if gp
== nil || gp
.m
== nil {
85 // The C call to Go came from a thread created by C.
86 // The C call to Go came from a thread not currently running
87 // any Go. In the case of -buildmode=c-archive or c-shared,
88 // this call may be coming in before package initialization
89 // is complete. Wait until it is.
94 if mp
.needextram || atomic
.Load(&extraMWaiters
) > 0 {
100 // CgocallBackDone prepares to return to C/C++ code that has called
102 func CgocallBackDone() {
103 // If we are the top level Go function called from C/C++, then
104 // we need to release the m. But don't release it if we are
105 // panicing; since this is the top level, we are going to
106 // crash the program, and we need the g and m to print the
109 // Dropping the m is going to clear g. This function is being
110 // called as a deferred function, so we will return to
111 // deferreturn which will want to clear the _defer field.
112 // As soon as we call dropm another thread may call needm and
113 // start using g, so we must not tamper with the _defer field
114 // after dropm. So clear _defer now.
118 if mp
.dropextram
&& mp
.ncgo
== 0 && gp
._panic
== nil {
120 if d
== nil || d
.link
!= nil {
121 throw("unexpected g._defer in CgocallBackDone")
132 mp
.dropextram
= false
137 // _cgo_panic may be called by SWIG code to panic.
138 func _cgo_panic(p
*byte) {
140 panic(gostringnocopy(p
))
143 // cgo_yield exists in the gc toolchain to let TSAN deliver a signal.
144 // gccgo does not need this.
145 var cgo_yield
= &_cgo_yield
146 var _cgo_yield unsafe
.Pointer