github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/sync/atomic/race.go (about)

     1  // Copyright 2011 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  package atomic
     8  
     9  import (
    10  	"runtime"
    11  	"unsafe"
    12  )
    13  
    14  // We use runtime.RaceRead() inside of atomic operations to catch races
    15  // between atomic and non-atomic operations.  It will also catch races
    16  // between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
    17  // only RaceRead() we won't catch races with non-atomic loads.
    18  // Otherwise (if we use RaceWrite()) we will report races
    19  // between atomic operations (false positives).
    20  
    21  var mtx uint32 = 1 // same for all
    22  
    23  func SwapInt32(addr *int32, new int32) (old int32) {
    24  	return int32(SwapUint32((*uint32)(unsafe.Pointer(addr)), uint32(new)))
    25  }
    26  
    27  func SwapUint32(addr *uint32, new uint32) (old uint32) {
    28  	_ = *addr
    29  	runtime.RaceSemacquire(&mtx)
    30  	runtime.RaceRead(unsafe.Pointer(addr))
    31  	runtime.RaceAcquire(unsafe.Pointer(addr))
    32  	old = *addr
    33  	*addr = new
    34  	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
    35  	runtime.RaceSemrelease(&mtx)
    36  	return
    37  }
    38  
    39  func SwapInt64(addr *int64, new int64) (old int64) {
    40  	return int64(SwapUint64((*uint64)(unsafe.Pointer(addr)), uint64(new)))
    41  }
    42  
    43  func SwapUint64(addr *uint64, new uint64) (old uint64) {
    44  	_ = *addr
    45  	runtime.RaceSemacquire(&mtx)
    46  	runtime.RaceRead(unsafe.Pointer(addr))
    47  	runtime.RaceAcquire(unsafe.Pointer(addr))
    48  	old = *addr
    49  	*addr = new
    50  	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
    51  	runtime.RaceSemrelease(&mtx)
    52  	return
    53  }
    54  
    55  func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) {
    56  	return uintptr(SwapPointer((*unsafe.Pointer)(unsafe.Pointer(addr)), unsafe.Pointer(new)))
    57  }
    58  
    59  func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) {
    60  	_ = *addr
    61  	runtime.RaceSemacquire(&mtx)
    62  	runtime.RaceRead(unsafe.Pointer(addr))
    63  	runtime.RaceAcquire(unsafe.Pointer(addr))
    64  	old = *addr
    65  	*addr = new
    66  	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
    67  	runtime.RaceSemrelease(&mtx)
    68  	return
    69  }
    70  
    71  func CompareAndSwapInt32(val *int32, old, new int32) bool {
    72  	return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
    73  }
    74  
    75  func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
    76  	_ = *val
    77  	swapped = false
    78  	runtime.RaceSemacquire(&mtx)
    79  	runtime.RaceRead(unsafe.Pointer(val))
    80  	runtime.RaceAcquire(unsafe.Pointer(val))
    81  	if *val == old {
    82  		*val = new
    83  		swapped = true
    84  		runtime.RaceReleaseMerge(unsafe.Pointer(val))
    85  	}
    86  	runtime.RaceSemrelease(&mtx)
    87  	return
    88  }
    89  
    90  func CompareAndSwapInt64(val *int64, old, new int64) bool {
    91  	return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
    92  }
    93  
    94  func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
    95  	_ = *val
    96  	swapped = false
    97  	runtime.RaceSemacquire(&mtx)
    98  	runtime.RaceRead(unsafe.Pointer(val))
    99  	runtime.RaceAcquire(unsafe.Pointer(val))
   100  	if *val == old {
   101  		*val = new
   102  		swapped = true
   103  		runtime.RaceReleaseMerge(unsafe.Pointer(val))
   104  	}
   105  	runtime.RaceSemrelease(&mtx)
   106  	return
   107  }
   108  
   109  func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
   110  	_ = *val
   111  	swapped = false
   112  	runtime.RaceSemacquire(&mtx)
   113  	runtime.RaceRead(unsafe.Pointer(val))
   114  	runtime.RaceAcquire(unsafe.Pointer(val))
   115  	if *val == old {
   116  		*val = new
   117  		swapped = true
   118  		runtime.RaceReleaseMerge(unsafe.Pointer(val))
   119  	}
   120  	runtime.RaceSemrelease(&mtx)
   121  	return
   122  }
   123  
   124  func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
   125  	_ = *val
   126  	swapped = false
   127  	runtime.RaceSemacquire(&mtx)
   128  	runtime.RaceRead(unsafe.Pointer(val))
   129  	runtime.RaceAcquire(unsafe.Pointer(val))
   130  	if *val == old {
   131  		*val = new
   132  		swapped = true
   133  		runtime.RaceReleaseMerge(unsafe.Pointer(val))
   134  	}
   135  	runtime.RaceSemrelease(&mtx)
   136  	return
   137  }
   138  
   139  func AddInt32(val *int32, delta int32) int32 {
   140  	return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
   141  }
   142  
   143  func AddUint32(val *uint32, delta uint32) (new uint32) {
   144  	_ = *val
   145  	runtime.RaceSemacquire(&mtx)
   146  	runtime.RaceRead(unsafe.Pointer(val))
   147  	runtime.RaceAcquire(unsafe.Pointer(val))
   148  	*val = *val + delta
   149  	new = *val
   150  	runtime.RaceReleaseMerge(unsafe.Pointer(val))
   151  	runtime.RaceSemrelease(&mtx)
   152  
   153  	return
   154  }
   155  
   156  func AddInt64(val *int64, delta int64) int64 {
   157  	return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
   158  }
   159  
   160  func AddUint64(val *uint64, delta uint64) (new uint64) {
   161  	_ = *val
   162  	runtime.RaceSemacquire(&mtx)
   163  	runtime.RaceRead(unsafe.Pointer(val))
   164  	runtime.RaceAcquire(unsafe.Pointer(val))
   165  	*val = *val + delta
   166  	new = *val
   167  	runtime.RaceReleaseMerge(unsafe.Pointer(val))
   168  	runtime.RaceSemrelease(&mtx)
   169  
   170  	return
   171  }
   172  
   173  func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
   174  	_ = *val
   175  	runtime.RaceSemacquire(&mtx)
   176  	runtime.RaceRead(unsafe.Pointer(val))
   177  	runtime.RaceAcquire(unsafe.Pointer(val))
   178  	*val = *val + delta
   179  	new = *val
   180  	runtime.RaceReleaseMerge(unsafe.Pointer(val))
   181  	runtime.RaceSemrelease(&mtx)
   182  
   183  	return
   184  }
   185  
   186  func LoadInt32(addr *int32) int32 {
   187  	return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
   188  }
   189  
   190  func LoadUint32(addr *uint32) (val uint32) {
   191  	_ = *addr
   192  	runtime.RaceSemacquire(&mtx)
   193  	runtime.RaceRead(unsafe.Pointer(addr))
   194  	runtime.RaceAcquire(unsafe.Pointer(addr))
   195  	val = *addr
   196  	runtime.RaceSemrelease(&mtx)
   197  	return
   198  }
   199  
   200  func LoadInt64(addr *int64) int64 {
   201  	return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
   202  }
   203  
   204  func LoadUint64(addr *uint64) (val uint64) {
   205  	_ = *addr
   206  	runtime.RaceSemacquire(&mtx)
   207  	runtime.RaceRead(unsafe.Pointer(addr))
   208  	runtime.RaceAcquire(unsafe.Pointer(addr))
   209  	val = *addr
   210  	runtime.RaceSemrelease(&mtx)
   211  	return
   212  }
   213  
   214  func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
   215  	_ = *addr
   216  	runtime.RaceSemacquire(&mtx)
   217  	runtime.RaceRead(unsafe.Pointer(addr))
   218  	runtime.RaceAcquire(unsafe.Pointer(addr))
   219  	val = *addr
   220  	runtime.RaceSemrelease(&mtx)
   221  	return
   222  }
   223  
   224  func LoadUintptr(addr *uintptr) (val uintptr) {
   225  	_ = *addr
   226  	runtime.RaceSemacquire(&mtx)
   227  	runtime.RaceRead(unsafe.Pointer(addr))
   228  	runtime.RaceAcquire(unsafe.Pointer(addr))
   229  	val = *addr
   230  	runtime.RaceSemrelease(&mtx)
   231  	return
   232  }
   233  
   234  func StoreInt32(addr *int32, val int32) {
   235  	StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
   236  }
   237  
   238  func StoreUint32(addr *uint32, val uint32) {
   239  	_ = *addr
   240  	runtime.RaceSemacquire(&mtx)
   241  	runtime.RaceRead(unsafe.Pointer(addr))
   242  	*addr = val
   243  	runtime.RaceRelease(unsafe.Pointer(addr))
   244  	runtime.RaceSemrelease(&mtx)
   245  }
   246  
   247  func StoreInt64(addr *int64, val int64) {
   248  	StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
   249  }
   250  
   251  func StoreUint64(addr *uint64, val uint64) {
   252  	_ = *addr
   253  	runtime.RaceSemacquire(&mtx)
   254  	runtime.RaceRead(unsafe.Pointer(addr))
   255  	*addr = val
   256  	runtime.RaceRelease(unsafe.Pointer(addr))
   257  	runtime.RaceSemrelease(&mtx)
   258  }
   259  
   260  func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
   261  	_ = *addr
   262  	runtime.RaceSemacquire(&mtx)
   263  	runtime.RaceRead(unsafe.Pointer(addr))
   264  	*addr = val
   265  	runtime.RaceRelease(unsafe.Pointer(addr))
   266  	runtime.RaceSemrelease(&mtx)
   267  }
   268  
   269  func StoreUintptr(addr *uintptr, val uintptr) {
   270  	_ = *addr
   271  	runtime.RaceSemacquire(&mtx)
   272  	runtime.RaceRead(unsafe.Pointer(addr))
   273  	*addr = val
   274  	runtime.RaceRelease(unsafe.Pointer(addr))
   275  	runtime.RaceSemrelease(&mtx)
   276  }