hppa: Fix ICE caused by mismatched predicate and constraint in xmpyu patterns
[official-gcc.git] / libgo / go / runtime / cgo_gccgo.go
blob520838afa4befded347f717c64229b96213ec723
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.
5 package runtime
7 import (
8 "runtime/internal/atomic"
9 "unsafe"
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
23 // to true.
24 var iscgo bool
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.
28 var cgoHasExtraM bool
30 // cgoAlwaysFalse is a boolean value that is always false.
31 // The cgo-generated code says if cgoAlwaysFalse { cgoUse(p) }.
32 // The compiler cannot see that cgoAlwaysFalse is always false,
33 // so it emits the test and keeps the call, giving the desired
34 // escape analysis result. The test is cheaper than the call.
35 var cgoAlwaysFalse bool
37 // Cgocall prepares to call from code written in Go to code written in
38 // C/C++. This takes the current goroutine out of the Go scheduler, as
39 // though it were making a system call. Otherwise the program can
40 // lookup if the C code blocks. The idea is to call this function,
41 // then immediately call the C/C++ function. After the C/C++ function
42 // returns, call cgocalldone. The usual Go code would look like
43 // syscall.Cgocall()
44 // defer syscall.Cgocalldone()
45 // cfunction()
46 func Cgocall() {
47 mp := getg().m
48 mp.ncgocall++
49 mp.ncgo++
50 entersyscall()
51 mp.incgo = true
54 // CgocallDone prepares to return to Go code from C/C++ code.
55 func CgocallDone() {
56 gp := getg()
57 if gp == nil {
58 throw("no g in CgocallDone")
60 gp.m.incgo = false
61 gp.m.ncgo--
63 // If we are invoked because the C function called _cgo_panic,
64 // then _cgo_panic will already have exited syscall mode.
65 if readgstatus(gp)&^_Gscan == _Gsyscall {
66 exitsyscall()
70 // CgocallBack is used when calling from C/C++ code into Go code.
71 // The usual approach is
72 // syscall.CgocallBack()
73 // defer syscall.CgocallBackDone()
74 // gofunction()
75 //go:nosplit
76 func CgocallBack() {
77 gp := getg()
78 if gp == nil || gp.m == nil {
79 needm()
80 gp = getg()
81 mp := gp.m
82 mp.dropextram = true
84 // This is a C-created stack.
85 // Record the outermost Go frame to help stack scan.
86 gp.entrysp = getcallersp()
89 lockOSThread()
91 gp.m.incgo = false
92 exitsyscall()
94 if gp.m.ncgo == 0 {
95 // The C call to Go came from a thread created by C.
96 // The C call to Go came from a thread not currently running
97 // any Go. In the case of -buildmode=c-archive or c-shared,
98 // this call may be coming in before package initialization
99 // is complete. Wait until it is.
100 <-main_init_done
103 mp := gp.m
104 if mp.needextram || atomic.Load(&extraMWaiters) > 0 {
105 mp.needextram = false
106 newextram()
110 // CgocallBackDone prepares to return to C/C++ code that has called
111 // into Go code.
112 func CgocallBackDone() {
113 unlockOSThread()
115 // We are going to stop running in Go mode and return to C mode.
116 // We were almost certainly called by defer; if so, clean up
117 // the defer struct now, before we leave Go mode. But don't
118 // leave Go mode if we are panicing or called from Goexit,
119 // since in those cases we will continue executing deferred functions.
120 gp := getg()
121 mp := gp.m
122 drop := false
123 if gp.deferring && gp._panic == nil && !gp.goexiting {
124 d := gp._defer
125 if d == nil {
126 throw("no defer struct when deferring")
128 gp._defer = d.link
129 freedefer(d)
131 // If we are the top level Go function called from C,
132 // then we need to release the m.
133 if mp.dropextram && mp.ncgo == 0 {
134 drop = true
138 // Don't go back to C mode if we are panicing. Just let the
139 // panic walk up through the Go stack.
140 if gp._panic == nil && !gp.goexiting {
141 gp.m.incgo = true
142 entersyscall()
145 if drop {
146 mp.dropextram = false
147 dropm()
148 } else if gp.deferring && gp._panic == nil && !gp.goexiting {
149 gp.ranCgocallBackDone = true
153 // _cgo_panic may be called by SWIG code to panic.
154 func _cgo_panic(p *byte) {
155 exitsyscall()
156 panic(gostringnocopy(p))
159 // cgo_yield exists in the gc toolchain to let TSAN deliver a signal.
160 // gccgo does not need this.
161 var cgo_yield = &_cgo_yield
162 var _cgo_yield unsafe.Pointer