Run Format

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

View as plain text