blob: 923d6113f685e4d6c5b96aa30a2822a7fa109c96 [file] [log] [blame]
Brent Austinba3052e2015-04-21 16:08:23 -07001// Copyright 2012 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// +build race
6
7// Public race detection API, present iff build with -race.
8
9package runtime
10
11import (
12 "unsafe"
13)
14
Brent Austinba3052e2015-04-21 16:08:23 -070015func RaceRead(addr unsafe.Pointer)
16func RaceWrite(addr unsafe.Pointer)
17func RaceReadRange(addr unsafe.Pointer, len int)
18func RaceWriteRange(addr unsafe.Pointer, len int)
19
20func RaceSemacquire(s *uint32)
21func RaceSemrelease(s *uint32)
22
23// private interface for the runtime
24const raceenabled = true
25
Dan Willemsen09eb3b12015-09-16 14:34:17 -070026// For all functions accepting callerpc and pc,
27// callerpc is a return PC of the function that calls this function,
28// pc is start PC of the function that calls this function.
Brent Austinba3052e2015-04-21 16:08:23 -070029func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
30 kind := t.kind & kindMask
31 if kind == kindArray || kind == kindStruct {
32 // for composite objects we have to read every address
33 // because a write might happen to any subobject.
34 racereadrangepc(addr, t.size, callerpc, pc)
35 } else {
36 // for non-composite objects we can read just the start
37 // address, as any write must write the first byte.
38 racereadpc(addr, callerpc, pc)
39 }
40}
41
42func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
43 kind := t.kind & kindMask
44 if kind == kindArray || kind == kindStruct {
45 // for composite objects we have to write every address
46 // because a write might happen to any subobject.
47 racewriterangepc(addr, t.size, callerpc, pc)
48 } else {
49 // for non-composite objects we can write just the start
50 // address, as any write must write the first byte.
51 racewritepc(addr, callerpc, pc)
52 }
53}
54
55//go:noescape
56func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
57
58//go:noescape
59func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
60
Brent Austinba3052e2015-04-21 16:08:23 -070061type symbolizeContext struct {
62 pc uintptr
63 fn *byte
64 file *byte
65 line uintptr
66 off uintptr
67 res uintptr
68}
69
70var qq = [...]byte{'?', '?', 0}
71var dash = [...]byte{'-', 0}
72
73// Callback from C into Go, runs on g0.
74func racesymbolize(ctx *symbolizeContext) {
75 f := findfunc(ctx.pc)
76 if f == nil {
77 ctx.fn = &qq[0]
78 ctx.file = &dash[0]
79 ctx.line = 0
80 ctx.off = ctx.pc
81 ctx.res = 1
82 return
83 }
84
Dan Willemsen09eb3b12015-09-16 14:34:17 -070085 ctx.fn = cfuncname(f)
86 file, line := funcline(f, ctx.pc)
87 ctx.line = uintptr(line)
Brent Austinba3052e2015-04-21 16:08:23 -070088 ctx.file = &bytes(file)[0] // assume NUL-terminated
89 ctx.off = ctx.pc - f.entry
90 ctx.res = 1
91 return
92}