Text file src/pkg/runtime/cgocall.c
1 // Copyright 2009 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.
4
5 #include "runtime.h"
6 #include "arch_GOARCH.h"
7 #include "stack.h"
8 #include "cgocall.h"
9 #include "race.h"
10
11 // Cgo call and callback support.
12 //
13 // To call into the C function f from Go, the cgo-generated code calls
14 // runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
15 // gcc-compiled function written by cgo.
16 //
17 // runtime.cgocall (below) locks g to m, calls entersyscall
18 // so as not to block other goroutines or the garbage collector,
19 // and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame).
20 //
21 // runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
22 // (assumed to be an operating system-allocated stack, so safe to run
23 // gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
24 //
25 // _cgo_Cfunc_f invokes the actual C function f with arguments
26 // taken from the frame structure, records the results in the frame,
27 // and returns to runtime.asmcgocall.
28 //
29 // After it regains control, runtime.asmcgocall switches back to the
30 // original g (m->curg)'s stack and returns to runtime.cgocall.
31 //
32 // After it regains control, runtime.cgocall calls exitsyscall, which blocks
33 // until this m can run Go code without violating the $GOMAXPROCS limit,
34 // and then unlocks g from m.
35 //
36 // The above description skipped over the possibility of the gcc-compiled
37 // function f calling back into Go. If that happens, we continue down
38 // the rabbit hole during the execution of f.
39 //
40 // To make it possible for gcc-compiled C code to call a Go function p.GoF,
41 // cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
42 // know about packages). The gcc-compiled C function f calls GoF.
43 //
44 // GoF calls crosscall2(_cgoexp_GoF, frame, framesize). Crosscall2
45 // (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
46 // adapter from the gcc function call ABI to the 6c function call ABI.
47 // It is called from gcc to call 6c functions. In this case it calls
48 // _cgoexp_GoF(frame, framesize), still running on m->g0's stack
49 // and outside the $GOMAXPROCS limit. Thus, this code cannot yet
50 // call arbitrary Go code directly and must be careful not to allocate
51 // memory or use up m->g0's stack.
52 //
53 // _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
54 // (The reason for having _cgoexp_GoF instead of writing a crosscall3
55 // to make this call directly is that _cgoexp_GoF, because it is compiled
56 // with 6c instead of gcc, can refer to dotted names like
57 // runtime.cgocallback and p.GoF.)
58 //
59 // runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
60 // stack to the original g (m->curg)'s stack, on which it calls
61 // runtime.cgocallbackg(p.GoF, frame, framesize).
62 // As part of the stack switch, runtime.cgocallback saves the current
63 // SP as m->g0->sched.sp, so that any use of m->g0's stack during the
64 // execution of the callback will be done below the existing stack frames.
65 // Before overwriting m->g0->sched.sp, it pushes the old value on the
66 // m->g0 stack, so that it can be restored later.
67 //
68 // runtime.cgocallbackg (below) is now running on a real goroutine
69 // stack (not an m->g0 stack). First it calls runtime.exitsyscall, which will
70 // block until the $GOMAXPROCS limit allows running this goroutine.
71 // Once exitsyscall has returned, it is safe to do things like call the memory
72 // allocator or invoke the Go callback function p.GoF. runtime.cgocallbackg
73 // first defers a function to unwind m->g0.sched.sp, so that if p.GoF
74 // panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
75 // and the m->curg stack will be unwound in lock step.
76 // Then it calls p.GoF. Finally it pops but does not execute the deferred
77 // function, calls runtime.entersyscall, and returns to runtime.cgocallback.
78 //
79 // After it regains control, runtime.cgocallback switches back to
80 // m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
81 // m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
82 //
83 // _cgoexp_GoF immediately returns to crosscall2, which restores the
84 // callee-save registers for gcc and returns to GoF, which returns to f.
85
86 void *_cgo_init; /* filled in by dynamic linker when Cgo is available */
87 static int64 cgosync; /* represents possible synchronization in C code */
88
89 // These two are only used by the architecture where TLS based storage isn't
90 // the default for g and m (e.g., ARM)
91 void *_cgo_load_gm; /* filled in by dynamic linker when Cgo is available */
92 void *_cgo_save_gm; /* filled in by dynamic linker when Cgo is available */
93
94 static void unwindm(void);
95
96 // Call from Go to C.
97
98 static void endcgo(void);
99 static FuncVal endcgoV = { endcgo };
100
101 // Gives a hint that the next syscall
102 // executed by the current goroutine will block.
103 // Currently used only on windows.
104 void
105 net·runtime_blockingSyscallHint(void)
106 {
107 g->blockingsyscall = true;
108 }
109
110 void
111 runtime·cgocall(void (*fn)(void*), void *arg)
112 {
113 Defer d;
114
115 if(m->racecall) {
116 runtime·asmcgocall(fn, arg);
117 return;
118 }
119
120 if(!runtime·iscgo && !Windows)
121 runtime·throw("cgocall unavailable");
122
123 if(fn == 0)
124 runtime·throw("cgocall nil");
125
126 if(raceenabled)
127 runtime·racereleasemerge(&cgosync);
128
129 m->ncgocall++;
130
131 /*
132 * Lock g to m to ensure we stay on the same stack if we do a
133 * cgo callback. Add entry to defer stack in case of panic.
134 */
135 runtime·lockOSThread();
136 d.fn = &endcgoV;
137 d.siz = 0;
138 d.link = g->defer;
139 d.argp = (void*)-1; // unused because unlockm never recovers
140 d.special = true;
141 d.free = false;
142 g->defer = &d;
143
144 m->ncgo++;
145
146 /*
147 * Announce we are entering a system call
148 * so that the scheduler knows to create another
149 * M to run goroutines while we are in the
150 * foreign code.
151 *
152 * The call to asmcgocall is guaranteed not to
153 * split the stack and does not allocate memory,
154 * so it is safe to call while "in a system call", outside
155 * the $GOMAXPROCS accounting.
156 */
157 if(g->blockingsyscall) {
158 g->blockingsyscall = false;
159 runtime·entersyscallblock();
160 } else
161 runtime·entersyscall();
162 runtime·asmcgocall(fn, arg);
163 runtime·exitsyscall();
164
165 if(g->defer != &d || d.fn != &endcgoV)
166 runtime·throw("runtime: bad defer entry in cgocallback");
167 g->defer = d.link;
168 endcgo();
169 }
170
171 static void
172 endcgo(void)
173 {
174 runtime·unlockOSThread();
175 m->ncgo--;
176 if(m->ncgo == 0) {
177 // We are going back to Go and are not in a recursive
178 // call. Let the GC collect any memory allocated via
179 // _cgo_allocate that is no longer referenced.
180 m->cgomal = nil;
181 }
182
183 if(raceenabled)
184 runtime·raceacquire(&cgosync);
185 }
186
187 void
188 runtime·NumCgoCall(int64 ret)
189 {
190 M *mp;
191
192 ret = 0;
193 for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
194 ret += mp->ncgocall;
195 FLUSH(&ret);
196 }
197
198 // Helper functions for cgo code.
199
200 void (*_cgo_malloc)(void*);
201 void (*_cgo_free)(void*);
202
203 void*
204 runtime·cmalloc(uintptr n)
205 {
206 struct {
207 uint64 n;
208 void *ret;
209 } a;
210
211 a.n = n;
212 a.ret = nil;
213 runtime·cgocall(_cgo_malloc, &a);
214 return a.ret;
215 }
216
217 void
218 runtime·cfree(void *p)
219 {
220 runtime·cgocall(_cgo_free, p);
221 }
222
223 // Call from C back to Go.
224
225 static FuncVal unwindmf = {unwindm};
226
227 void
228 runtime·cgocallbackg(FuncVal *fn, void *arg, uintptr argsize)
229 {
230 Defer d;
231
232 if(m->racecall) {
233 reflect·call(fn, arg, argsize);
234 return;
235 }
236
237 if(g != m->curg)
238 runtime·throw("runtime: bad g in cgocallback");
239
240 runtime·exitsyscall(); // coming out of cgo call
241
242 if(m->needextram) {
243 m->needextram = 0;
244 runtime·newextram();
245 }
246
247 // Add entry to defer stack in case of panic.
248 d.fn = &unwindmf;
249 d.siz = 0;
250 d.link = g->defer;
251 d.argp = (void*)-1; // unused because unwindm never recovers
252 d.special = true;
253 d.free = false;
254 g->defer = &d;
255
256 if(raceenabled)
257 runtime·raceacquire(&cgosync);
258
259 // Invoke callback.
260 reflect·call(fn, arg, argsize);
261
262 if(raceenabled)
263 runtime·racereleasemerge(&cgosync);
264
265 // Pop defer.
266 // Do not unwind m->g0->sched.sp.
267 // Our caller, cgocallback, will do that.
268 if(g->defer != &d || d.fn != &unwindmf)
269 runtime·throw("runtime: bad defer entry in cgocallback");
270 g->defer = d.link;
271
272 runtime·entersyscall(); // going back to cgo call
273 }
274
275 static void
276 unwindm(void)
277 {
278 // Restore sp saved by cgocallback during
279 // unwind of g's stack (see comment at top of file).
280 switch(thechar){
281 default:
282 runtime·throw("runtime: unwindm not implemented");
283 case '8':
284 case '6':
285 case '5':
286 m->g0->sched.sp = *(uintptr*)m->g0->sched.sp;
287 break;
288 }
289 }
290
291 void
292 runtime·badcgocallback(void) // called from assembly
293 {
294 runtime·throw("runtime: misaligned stack in cgocallback");
295 }
296
297 void
298 runtime·cgounimpl(void) // called from (incomplete) assembly
299 {
300 runtime·throw("runtime: cgo not implemented");
301 }
302
303 // For cgo-using programs with external linking,
304 // export "main" (defined in assembly) so that libc can handle basic
305 // C runtime startup and call the Go program as if it were
306 // the C main function.
307 #pragma cgo_export_static main
View as plain text