diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-12-19 18:00:35 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-12-19 18:00:35 +0000 |
commit | 0d3dd8fb65050363f1f82b5f048799fd9a0a0f5a (patch) | |
tree | 2ebab7c43a3260f883a2cf83ca162d10a8850870 /libgo/go/runtime/cgo_gccgo.go | |
parent | 4daecdb62396a1571f3cba861a0068ab539f8e28 (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.go | 110 |
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)) +} |