summaryrefslogtreecommitdiff
path: root/libgo/misc/cgo/testsanitizers/tsan2.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/misc/cgo/testsanitizers/tsan2.go')
-rw-r--r--libgo/misc/cgo/testsanitizers/tsan2.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/libgo/misc/cgo/testsanitizers/tsan2.go b/libgo/misc/cgo/testsanitizers/tsan2.go
new file mode 100644
index 00000000000..5018a1987ca
--- /dev/null
+++ b/libgo/misc/cgo/testsanitizers/tsan2.go
@@ -0,0 +1,55 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// This program produced false race reports when run under the C/C++
+// ThreadSanitizer, as it did not understand the synchronization in
+// the Go code.
+
+/*
+#cgo CFLAGS: -fsanitize=thread
+#cgo LDFLAGS: -fsanitize=thread
+
+extern void GoRun(void);
+
+// Yes, you can have definitions if you use //export, as long as they are weak.
+
+int val __attribute__ ((weak));
+
+int run(void) __attribute__ ((weak));
+
+int run() {
+ val = 1;
+ GoRun();
+ return val;
+}
+
+void setVal(int) __attribute__ ((weak));
+
+void setVal(int i) {
+ val = i;
+}
+*/
+import "C"
+
+import "runtime"
+
+//export GoRun
+func GoRun() {
+ runtime.LockOSThread()
+ c := make(chan bool)
+ go func() {
+ runtime.LockOSThread()
+ C.setVal(2)
+ c <- true
+ }()
+ <-c
+}
+
+func main() {
+ if v := C.run(); v != 2 {
+ panic(v)
+ }
+}