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 */
8 void
9 x_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
27 void(* const _cgo_yield)() = NULL;
28 #else
29
30 #include <string.h>
31
32 char x_cgo_yield_strncpy_src = 0;
33 char x_cgo_yield_strncpy_dst = 0;
34 size_t x_cgo_yield_strncpy_n = 0;
35
36 /*
37 Stub for allowing libc interceptors to execute.
38
39 _cgo_yield is set to NULL if we do not expect libc interceptors to exist.
40 */
41 static void
42 x_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
67 void(* const _cgo_yield)() = &x_cgo_yield;
68
69 #endif /* GO_TSAN */
70
View as plain text