]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add RaceRead/RaceWrite functions
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 14 Nov 2012 12:51:23 +0000 (16:51 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 14 Nov 2012 12:51:23 +0000 (16:51 +0400)
It allows to catch e.g. a data race between atomic write and non-atomic write,
or Mutex.Lock() and mutex overwrite (e.g. mu = Mutex{}).

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6817103

src/pkg/runtime/race.c
src/pkg/runtime/race.go
src/pkg/sync/atomic/race.go

index a89986ad404be84c7495acdce9d367ee3cb48d0e..23866f01d1a814310b613151d32fcf2539e2fad0 100644 (file)
@@ -254,6 +254,22 @@ void runtime·RaceSemrelease(uint32 *s)
        runtime·semrelease(s);
 }
 
+// func RaceRead(addr unsafe.Pointer)
+#pragma textflag 7
+void
+runtime·RaceRead(void *addr)
+{
+       runtime·racereadpc(addr, runtime·getcallerpc(&addr));
+}
+
+// func RaceWrite(addr unsafe.Pointer)
+#pragma textflag 7
+void
+runtime·RaceWrite(void *addr)
+{
+       runtime·racewritepc(addr, runtime·getcallerpc(&addr));
+}
+
 // func RaceDisable()
 void runtime·RaceDisable(void)
 {
index a3d7256072a0333ae9ce28b60b2e4a2af3d489d9..1d64ba3894e4f3dd17757938e238ecbf15711642 100644 (file)
@@ -22,5 +22,8 @@ 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 RaceSemacquire(s *uint32)
 func RaceSemrelease(s *uint32)
index c3627654deb3ba7f2997145ea29377117b03a2c6..049440205d25ccbebc2deaeb44ac06017f513329 100644 (file)
@@ -11,6 +11,13 @@ import (
        "unsafe"
 )
 
+// We use runtime.RaceRead() inside of atomic operations to catch races
+// between atomic and non-atomic operations.  It will also catch races
+// between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
+// only RaceRead() we won't catch races with non-atomic loads.
+// Otherwise (if we use RaceWrite()) we will report races
+// between atomic operations (false positives).
+
 var mtx uint32 = 1 // same for all
 
 func CompareAndSwapInt32(val *int32, old, new int32) bool {
@@ -20,6 +27,7 @@ func CompareAndSwapInt32(val *int32, old, new int32) bool {
 func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
        swapped = false
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        if *val == old {
                *val = new
@@ -37,6 +45,7 @@ func CompareAndSwapInt64(val *int64, old, new int64) bool {
 func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
        swapped = false
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        if *val == old {
                *val = new
@@ -50,6 +59,7 @@ func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
 func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
        swapped = false
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        if *val == old {
                *val = new
@@ -63,6 +73,7 @@ func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swappe
 func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
        swapped = false
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        if *val == old {
                *val = new
@@ -79,6 +90,7 @@ func AddInt32(val *int32, delta int32) int32 {
 
 func AddUint32(val *uint32, delta uint32) (new uint32) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        *val = *val + delta
        new = *val
@@ -94,6 +106,7 @@ func AddInt64(val *int64, delta int64) int64 {
 
 func AddUint64(val *uint64, delta uint64) (new uint64) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        *val = *val + delta
        new = *val
@@ -105,6 +118,7 @@ func AddUint64(val *uint64, delta uint64) (new uint64) {
 
 func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(val))
        *val = *val + delta
        new = *val
@@ -120,6 +134,7 @@ func LoadInt32(addr *int32) int32 {
 
 func LoadUint32(addr *uint32) (val uint32) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(addr))
        runtime.RaceAcquire(unsafe.Pointer(addr))
        val = *addr
        runtime.RaceSemrelease(&mtx)
@@ -132,6 +147,7 @@ func LoadInt64(addr *int64) int64 {
 
 func LoadUint64(addr *uint64) (val uint64) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(addr))
        runtime.RaceAcquire(unsafe.Pointer(addr))
        val = *addr
        runtime.RaceSemrelease(&mtx)
@@ -140,6 +156,7 @@ func LoadUint64(addr *uint64) (val uint64) {
 
 func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(addr))
        runtime.RaceAcquire(unsafe.Pointer(addr))
        val = *addr
        runtime.RaceSemrelease(&mtx)
@@ -148,6 +165,7 @@ func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
 
 func LoadUintptr(addr *uintptr) (val uintptr) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        runtime.RaceAcquire(unsafe.Pointer(addr))
        val = *addr
        runtime.RaceSemrelease(&mtx)
@@ -160,6 +178,7 @@ func StoreInt32(addr *int32, val int32) {
 
 func StoreUint32(addr *uint32, val uint32) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(addr))
        *addr = val
        runtime.RaceRelease(unsafe.Pointer(addr))
        runtime.RaceSemrelease(&mtx)
@@ -171,6 +190,7 @@ func StoreInt64(addr *int64, val int64) {
 
 func StoreUint64(addr *uint64, val uint64) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(addr))
        *addr = val
        runtime.RaceRelease(unsafe.Pointer(addr))
        runtime.RaceSemrelease(&mtx)
@@ -178,6 +198,7 @@ func StoreUint64(addr *uint64, val uint64) {
 
 func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        *addr = val
        runtime.RaceRelease(unsafe.Pointer(addr))
        runtime.RaceSemrelease(&mtx)
@@ -185,6 +206,7 @@ func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
 
 func StoreUintptr(addr *uintptr, val uintptr) {
        runtime.RaceSemacquire(&mtx)
+       runtime.RaceRead(unsafe.Pointer(val))
        *addr = val
        runtime.RaceRelease(unsafe.Pointer(addr))
        runtime.RaceSemrelease(&mtx)