...

Text file src/runtime/cgo/gcc_util.c

Documentation: runtime/cgo

		 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 "libcgo.h"
		 6
		 7/* Stub for creating a new thread */
		 8void
		 9x_cgo_thread_start(ThreadStart *arg)
		10{
		11	ThreadStart *ts;
		12
		13	/* Make our own copy that can persist after we return. */
		14	_cgo_tsan_acquire();
		15	ts = malloc(sizeof *ts);
		16	_cgo_tsan_release();
		17	if(ts == nil) {
		18		fprintf(stderr, "runtime/cgo: out of memory in thread_start\n");
		19		abort();
		20	}
		21	*ts = *arg;
		22
		23	_cgo_sys_thread_start(ts);	/* OS-dependent half */
		24}
		25
		26#ifndef CGO_TSAN
		27void(* const _cgo_yield)() = NULL;
		28#else
		29
		30#include <string.h>
		31
		32char x_cgo_yield_strncpy_src = 0;
		33char x_cgo_yield_strncpy_dst = 0;
		34size_t x_cgo_yield_strncpy_n = 0;
		35
		36/*
		37Stub for allowing libc interceptors to execute.
		38
		39_cgo_yield is set to NULL if we do not expect libc interceptors to exist.
		40*/
		41static void
		42x_cgo_yield()
		43{
		44	/*
		45	The libc function(s) we call here must form a no-op and include at least one
		46	call that triggers TSAN to process pending asynchronous signals.
		47
		48	sleep(0) would be fine, but it's not portable C (so it would need more header
		49	guards).
		50	free(NULL) has a fast-path special case in TSAN, so it doesn't
		51	trigger signal delivery.
		52	free(malloc(0)) would work (triggering the interceptors in malloc), but
		53	it also runs a bunch of user-supplied malloc hooks.
		54
		55	So we choose strncpy(_, _, 0): it requires an extra header,
		56	but it's standard and should be very efficient.
		57
		58	GCC 7 has an unfortunate habit of optimizing out strncpy calls (see
		59	https://golang.org/issue/21196), so the arguments here need to be global
		60	variables with external linkage in order to ensure that the call traps all the
		61	way down into libc.
		62	*/
		63	strncpy(&x_cgo_yield_strncpy_dst, &x_cgo_yield_strncpy_src,
		64					x_cgo_yield_strncpy_n);
		65}
		66
		67void(* const _cgo_yield)() = &x_cgo_yield;
		68
		69#endif	/* GO_TSAN */

View as plain text