github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/src/runtime/internal/atomic/atomic_mipsx.go (about)

     1  // Copyright 2016 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 mips mipsle
     6  
     7  package atomic
     8  
     9  import (
    10  	"runtime/internal/sys"
    11  	"unsafe"
    12  )
    13  
    14  // TODO implement lock striping
    15  var lock struct {
    16  	state uint32
    17  	pad   [sys.CacheLineSize - 4]byte
    18  }
    19  
    20  //go:noescape
    21  func spinLock(state *uint32)
    22  
    23  //go:noescape
    24  func spinUnlock(state *uint32)
    25  
    26  //go:nosplit
    27  func lockAndCheck(addr *uint64) {
    28  	//  force dereference before taking lock
    29  	_ = *addr
    30  
    31  	spinLock(&lock.state)
    32  }
    33  
    34  //go:nosplit
    35  func unlock() {
    36  	spinUnlock(&lock.state)
    37  }
    38  
    39  //go:nosplit
    40  func unlockNoFence() {
    41  	lock.state = 0
    42  }
    43  
    44  //go:nosplit
    45  func Xadd64(addr *uint64, delta int64) (new uint64) {
    46  	lockAndCheck(addr)
    47  
    48  	new = *addr + uint64(delta)
    49  	*addr = new
    50  
    51  	unlock()
    52  	return
    53  }
    54  
    55  //go:nosplit
    56  func Xchg64(addr *uint64, new uint64) (old uint64) {
    57  	lockAndCheck(addr)
    58  
    59  	old = *addr
    60  	*addr = new
    61  
    62  	unlock()
    63  	return
    64  }
    65  
    66  //go:nosplit
    67  func Cas64(addr *uint64, old, new uint64) (swapped bool) {
    68  	lockAndCheck(addr)
    69  
    70  	if (*addr) == old {
    71  		*addr = new
    72  		unlock()
    73  		return true
    74  	}
    75  
    76  	unlockNoFence()
    77  	return false
    78  }
    79  
    80  //go:nosplit
    81  func Load64(addr *uint64) (val uint64) {
    82  	lockAndCheck(addr)
    83  
    84  	val = *addr
    85  
    86  	unlock()
    87  	return
    88  }
    89  
    90  //go:nosplit
    91  func Store64(addr *uint64, val uint64) {
    92  	lockAndCheck(addr)
    93  
    94  	*addr = val
    95  
    96  	unlock()
    97  	return
    98  }
    99  
   100  //go:noescape
   101  func Xadd(ptr *uint32, delta int32) uint32
   102  
   103  //go:noescape
   104  func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
   105  
   106  //go:noescape
   107  func Xchg(ptr *uint32, new uint32) uint32
   108  
   109  //go:noescape
   110  func Xchguintptr(ptr *uintptr, new uintptr) uintptr
   111  
   112  //go:noescape
   113  func Load(ptr *uint32) uint32
   114  
   115  //go:noescape
   116  func Loadp(ptr unsafe.Pointer) unsafe.Pointer
   117  
   118  //go:noescape
   119  func And8(ptr *uint8, val uint8)
   120  
   121  //go:noescape
   122  func Or8(ptr *uint8, val uint8)
   123  
   124  //go:noescape
   125  func Store(ptr *uint32, val uint32)
   126  
   127  // NO go:noescape annotation; see atomic_pointer.go.
   128  func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)