summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/cgo_gccgo.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-12-19 18:00:35 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-12-19 18:00:35 +0000
commit0d3dd8fb65050363f1f82b5f048799fd9a0a0f5a (patch)
tree2ebab7c43a3260f883a2cf83ca162d10a8850870 /libgo/go/runtime/cgo_gccgo.go
parent4daecdb62396a1571f3cba861a0068ab539f8e28 (diff)
runtime: copy cgo support from Go 1.7 runtime
Remove support for _cgo_allocate. It was removed from the gc toolchain in Go 1.5, so it is unlikely that anybody is trying to use it. Reviewed-on: https://go-review.googlesource.com/34557 From-SVN: r243805
Diffstat (limited to 'libgo/go/runtime/cgo_gccgo.go')
-rw-r--r--libgo/go/runtime/cgo_gccgo.go110
1 files changed, 110 insertions, 0 deletions
diff --git a/libgo/go/runtime/cgo_gccgo.go b/libgo/go/runtime/cgo_gccgo.go
new file mode 100644
index 00000000000..a55fb436bc5
--- /dev/null
+++ b/libgo/go/runtime/cgo_gccgo.go
@@ -0,0 +1,110 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ _ "unsafe"
+)
+
+// For historical reasons these functions are called as though they
+// were in the syscall package.
+//go:linkname Cgocall syscall.Cgocall
+//go:linkname CgocallDone syscall.CgocallDone
+//go:linkname CgocallBack syscall.CgocallBack
+//go:linkname CgocallBackDone syscall.CgocallBackDone
+
+// A routine that may be called by SWIG.
+//go:linkname _cgo_panic _cgo_panic
+
+// iscgo is set to true if the cgo tool sets the C variable runtime_iscgo
+// to true.
+var iscgo bool
+
+// cgoHasExtraM is set on startup when an extra M is created for cgo.
+// The extra M must be created before any C/C++ code calls cgocallback.
+var cgoHasExtraM bool
+
+// Cgocall prepares to call from code written in Go to code written in
+// C/C++. This takes the current goroutine out of the Go scheduler, as
+// though it were making a system call. Otherwise the program can
+// lookup if the C code blocks. The idea is to call this function,
+// then immediately call the C/C++ function. After the C/C++ function
+// returns, call cgocalldone. The usual Go code would look like
+// syscall.Cgocall()
+// defer syscall.Cgocalldone()
+// cfunction()
+func Cgocall() {
+ lockOSThread()
+ mp := getg().m
+ mp.ncgocall++
+ mp.ncgo++
+ entersyscall(0)
+}
+
+// CgocallDone prepares to return to Go code from C/C++ code.
+func CgocallDone() {
+ gp := getg()
+ if gp == nil {
+ throw("no g in CgocallDone")
+ }
+ gp.m.ncgo--
+
+ // If we are invoked because the C function called _cgo_panic,
+ // then _cgo_panic will already have exited syscall mode.
+ if gp.atomicstatus == _Gsyscall {
+ exitsyscall(0)
+ }
+
+ unlockOSThread()
+}
+
+// CgocallBack is used when calling from C/C++ code into Go code.
+// The usual approach is
+// syscall.CgocallBack()
+// defer syscall.CgocallBackDone()
+// gofunction()
+//go:nosplit
+func CgocallBack() {
+ if getg() == nil || getg().m == nil {
+ needm(0)
+ mp := getg().m
+ mp.dropextram = true
+ }
+
+ exitsyscall(0)
+
+ if getg().m.ncgo == 0 {
+ // The C call to Go came from a thread created by C.
+ // The C call to Go came from a thread not currently running
+ // any Go. In the case of -buildmode=c-archive or c-shared,
+ // this call may be coming in before package initialization
+ // is complete. Wait until it is.
+ <-main_init_done
+ }
+
+ mp := getg().m
+ if mp.needextram || atomic.Load(&extraMWaiters) > 0 {
+ mp.needextram = false
+ newextram()
+ }
+}
+
+// CgocallBackDone prepares to return to C/C++ code that has called
+// into Go code.
+func CgocallBackDone() {
+ entersyscall(0)
+ mp := getg().m
+ if mp.dropextram && mp.ncgo == 0 {
+ mp.dropextram = false
+ dropm()
+ }
+}
+
+// _cgo_panic may be called by SWIG code to panic.
+func _cgo_panic(p *byte) {
+ exitsyscall(0)
+ panic(gostringnocopy(p))
+}