LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // +build race,linux,amd64 race,darwin,amd64 race,windows,amd64 | 5 // +build race,linux,amd64 race,darwin,amd64 race,windows,amd64 |
6 | 6 |
7 package race | 7 package race |
8 | 8 |
9 /* | 9 // This file merely ensures that we link in runtime/cgo in race build, |
10 void __tsan_init(void **racectx); | 10 // this is turn ensures that runtime uses pthread_create to create threads. |
11 void __tsan_fini(void); | 11 // The prebuilt race runtime lives in race_GOOS_GOARCH.syso. |
12 void __tsan_map_shadow(void *addr, void *size); | 12 // Calls to the runtime are done directly from src/pkg/runtime/race.c. |
13 void __tsan_go_start(void *racectx, void **chracectx, void *pc); | 13 |
14 void __tsan_go_end(void *racectx); | 14 // void __race_unused_func(void); |
15 void __tsan_read(void *racectx, void *addr, void *pc); | |
16 void __tsan_write(void *racectx, void *addr, void *pc); | |
17 void __tsan_read_range(void *racectx, void *addr, long sz, long step, void *pc); | |
18 void __tsan_write_range(void *racectx, void *addr, long sz, long step, void *pc)
; | |
19 void __tsan_func_enter(void *racectx, void *pc); | |
20 void __tsan_func_exit(void *racectx); | |
21 void __tsan_malloc(void *racectx, void *p, long sz, void *pc); | |
22 void __tsan_free(void *p); | |
23 void __tsan_acquire(void *racectx, void *addr); | |
24 void __tsan_release(void *racectx, void *addr); | |
25 void __tsan_release_merge(void *racectx, void *addr); | |
26 void __tsan_finalizer_goroutine(void *racectx); | |
27 */ | |
28 import "C" | 15 import "C" |
29 | |
30 import ( | |
31 "runtime" | |
32 "unsafe" | |
33 ) | |
34 | |
35 func Initialize(racectx *uintptr) { | |
36 C.__tsan_init((*unsafe.Pointer)(unsafe.Pointer(racectx))) | |
37 } | |
38 | |
39 func Finalize() { | |
40 C.__tsan_fini() | |
41 } | |
42 | |
43 func MapShadow(addr, size uintptr) { | |
44 C.__tsan_map_shadow(unsafe.Pointer(addr), unsafe.Pointer(size)) | |
45 } | |
46 | |
47 func FinalizerGoroutine(racectx uintptr) { | |
48 C.__tsan_finalizer_goroutine(unsafe.Pointer(racectx)) | |
49 } | |
50 | |
51 /* | |
52 func Read(racectx uintptr, addr, pc uintptr) { | |
53 C.__tsan_read(unsafe.Pointer(racectx), unsafe.Pointer(addr), unsafe.Poin
ter(pc)) | |
54 } | |
55 | |
56 func Write(racectx uintptr, addr, pc uintptr) { | |
57 C.__tsan_write(unsafe.Pointer(racectx), unsafe.Pointer(addr), unsafe.Poi
nter(pc)) | |
58 } | |
59 | |
60 func ReadRange(racectx uintptr, addr, sz, pc uintptr) { | |
61 C.__tsan_read_range(unsafe.Pointer(racectx), unsafe.Pointer(addr), | |
62 C.long(sz), 0, unsafe.Pointer(pc)) | |
63 } | |
64 | |
65 func WriteRange(racectx uintptr, addr, sz, pc uintptr) { | |
66 C.__tsan_write_range(unsafe.Pointer(racectx), unsafe.Pointer(addr), | |
67 C.long(sz), 0, unsafe.Pointer(pc)) | |
68 } | |
69 | |
70 func FuncEnter(racectx uintptr, pc uintptr) { | |
71 C.__tsan_func_enter(unsafe.Pointer(racectx), unsafe.Pointer(pc)) | |
72 } | |
73 | |
74 func FuncExit(racectx uintptr) { | |
75 C.__tsan_func_exit(unsafe.Pointer(racectx)) | |
76 } | |
77 */ | |
78 | |
79 func Malloc(racectx uintptr, p, sz, pc uintptr) { | |
80 C.__tsan_malloc(unsafe.Pointer(racectx), unsafe.Pointer(p), C.long(sz),
unsafe.Pointer(pc)) | |
81 } | |
82 | |
83 func Free(p uintptr) { | |
84 C.__tsan_free(unsafe.Pointer(p)) | |
85 } | |
86 | |
87 func GoStart(racectx uintptr, chracectx *uintptr, pc uintptr) { | |
88 C.__tsan_go_start(unsafe.Pointer(racectx), (*unsafe.Pointer)(unsafe.Poin
ter(chracectx)), unsafe.Pointer(pc)) | |
89 } | |
90 | |
91 func GoEnd(racectx uintptr) { | |
92 C.__tsan_go_end(unsafe.Pointer(racectx)) | |
93 } | |
94 | |
95 func Acquire(racectx uintptr, addr uintptr) { | |
96 C.__tsan_acquire(unsafe.Pointer(racectx), unsafe.Pointer(addr)) | |
97 } | |
98 | |
99 func Release(racectx uintptr, addr uintptr) { | |
100 C.__tsan_release(unsafe.Pointer(racectx), unsafe.Pointer(addr)) | |
101 } | |
102 | |
103 func ReleaseMerge(racectx uintptr, addr uintptr) { | |
104 C.__tsan_release_merge(unsafe.Pointer(racectx), unsafe.Pointer(addr)) | |
105 } | |
106 | |
107 //export __tsan_symbolize | |
108 func __tsan_symbolize(pc uintptr, fun, file **C.char, line, off *C.int) C.int { | |
109 f := runtime.FuncForPC(pc) | |
110 if f == nil { | |
111 *fun = C.CString("??") | |
112 *file = C.CString("-") | |
113 *line = 0 | |
114 *off = C.int(pc) | |
115 return 1 | |
116 } | |
117 fi, l := f.FileLine(pc) | |
118 *fun = C.CString(f.Name()) | |
119 *file = C.CString(fi) | |
120 *line = C.int(l) | |
121 *off = C.int(pc - f.Entry()) | |
122 return 1 | |
123 } | |
LEFT | RIGHT |