diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 12:50:40 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 12:50:40 -0700 |
commit | 2a0db60599fdd75b1bc3e297180fbe1282763759 (patch) | |
tree | 68d43c3e30d9ab961ddf6b7365201ca6b675b253 /src/runtime/race.go | |
parent | ef33cba3c8de6c431df56503df51fcd3a473c89e (diff) | |
parent | f154da9e12608589e8d5f0508f908a0c3e88a1bb (diff) | |
download | golang-2a0db60599fdd75b1bc3e297180fbe1282763759.tar.gz |
Merge tag 'upstream/1.4' into debian-experimental
* tag 'upstream/1.4':
Imported Upstream version 1.4
Diffstat (limited to 'src/runtime/race.go')
-rw-r--r-- | src/runtime/race.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/runtime/race.go b/src/runtime/race.go new file mode 100644 index 000000000..bb0ee6df6 --- /dev/null +++ b/src/runtime/race.go @@ -0,0 +1,127 @@ +// Copyright 2012 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. + +// +build race + +// Public race detection API, present iff build with -race. + +package runtime + +import ( + "unsafe" +) + +func racefini() + +// RaceDisable disables handling of race events in the current goroutine. +func RaceDisable() + +// RaceEnable re-enables handling of race events in the current goroutine. +func RaceEnable() + +func RaceAcquire(addr unsafe.Pointer) +func RaceRelease(addr unsafe.Pointer) +func RaceReleaseMerge(addr unsafe.Pointer) + +func RaceRead(addr unsafe.Pointer) +func RaceWrite(addr unsafe.Pointer) +func RaceReadRange(addr unsafe.Pointer, len int) +func RaceWriteRange(addr unsafe.Pointer, len int) + +func RaceSemacquire(s *uint32) +func RaceSemrelease(s *uint32) + +// private interface for the runtime +const raceenabled = true + +func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { + kind := t.kind & kindMask + if kind == kindArray || kind == kindStruct { + // for composite objects we have to read every address + // because a write might happen to any subobject. + racereadrangepc(addr, t.size, callerpc, pc) + } else { + // for non-composite objects we can read just the start + // address, as any write must write the first byte. + racereadpc(addr, callerpc, pc) + } +} + +func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { + kind := t.kind & kindMask + if kind == kindArray || kind == kindStruct { + // for composite objects we have to write every address + // because a write might happen to any subobject. + racewriterangepc(addr, t.size, callerpc, pc) + } else { + // for non-composite objects we can write just the start + // address, as any write must write the first byte. + racewritepc(addr, callerpc, pc) + } +} + +//go:noescape +func racereadpc(addr unsafe.Pointer, callpc, pc uintptr) + +//go:noescape +func racewritepc(addr unsafe.Pointer, callpc, pc uintptr) + +//go:noescape +func racereadrangepc(addr unsafe.Pointer, len uintptr, callpc, pc uintptr) + +//go:noescape +func racewriterangepc(addr unsafe.Pointer, len uintptr, callpc, pc uintptr) + +//go:noescape +func raceacquire(addr unsafe.Pointer) + +//go:noescape +func racerelease(addr unsafe.Pointer) + +//go:noescape +func raceacquireg(gp *g, addr unsafe.Pointer) + +//go:noescape +func racereleaseg(gp *g, addr unsafe.Pointer) + +func racefingo() + +//go:noescape +func racemalloc(p unsafe.Pointer, size uintptr) + +//go:noescape +func racereleasemerge(addr unsafe.Pointer) + +type symbolizeContext struct { + pc uintptr + fn *byte + file *byte + line uintptr + off uintptr + res uintptr +} + +var qq = [...]byte{'?', '?', 0} +var dash = [...]byte{'-', 0} + +// Callback from C into Go, runs on g0. +func racesymbolize(ctx *symbolizeContext) { + f := findfunc(ctx.pc) + if f == nil { + ctx.fn = &qq[0] + ctx.file = &dash[0] + ctx.line = 0 + ctx.off = ctx.pc + ctx.res = 1 + return + } + + ctx.fn = funcname(f) + var file string + ctx.line = uintptr(funcline(f, ctx.pc, &file)) + ctx.file = &bytes(file)[0] // assume NUL-terminated + ctx.off = ctx.pc - f.entry + ctx.res = 1 + return +} |