github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/runtime/race.go (about) 1 // 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 9 package runtime 10 11 import ( 12 "unsafe" 13 ) 14 15 func RaceRead(addr unsafe.Pointer) 16 func RaceWrite(addr unsafe.Pointer) 17 func RaceReadRange(addr unsafe.Pointer, len int) 18 func RaceWriteRange(addr unsafe.Pointer, len int) 19 20 func RaceSemacquire(s *uint32) 21 func RaceSemrelease(s *uint32) 22 23 // private interface for the runtime 24 const raceenabled = true 25 26 func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { 27 kind := t.kind & kindMask 28 if kind == kindArray || kind == kindStruct { 29 // for composite objects we have to read every address 30 // because a write might happen to any subobject. 31 racereadrangepc(addr, t.size, callerpc, pc) 32 } else { 33 // for non-composite objects we can read just the start 34 // address, as any write must write the first byte. 35 racereadpc(addr, callerpc, pc) 36 } 37 } 38 39 func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { 40 kind := t.kind & kindMask 41 if kind == kindArray || kind == kindStruct { 42 // for composite objects we have to write every address 43 // because a write might happen to any subobject. 44 racewriterangepc(addr, t.size, callerpc, pc) 45 } else { 46 // for non-composite objects we can write just the start 47 // address, as any write must write the first byte. 48 racewritepc(addr, callerpc, pc) 49 } 50 } 51 52 //go:noescape 53 func racereadpc(addr unsafe.Pointer, callpc, pc uintptr) 54 55 //go:noescape 56 func racewritepc(addr unsafe.Pointer, callpc, pc uintptr) 57 58 type symbolizeContext struct { 59 pc uintptr 60 fn *byte 61 file *byte 62 line uintptr 63 off uintptr 64 res uintptr 65 } 66 67 var qq = [...]byte{'?', '?', 0} 68 var dash = [...]byte{'-', 0} 69 70 // Callback from C into Go, runs on g0. 71 func racesymbolize(ctx *symbolizeContext) { 72 f := findfunc(ctx.pc) 73 if f == nil { 74 ctx.fn = &qq[0] 75 ctx.file = &dash[0] 76 ctx.line = 0 77 ctx.off = ctx.pc 78 ctx.res = 1 79 return 80 } 81 82 ctx.fn = funcname(f) 83 file, line := funcline(f, ctx.pc) 84 ctx.line = uintptr(line) 85 ctx.file = &bytes(file)[0] // assume NUL-terminated 86 ctx.off = ctx.pc - f.entry 87 ctx.res = 1 88 return 89 }