Black Lives Matter. Support the Equal Justice Initiative.

Source file src/runtime/internal/atomic/atomic_mipsx.go

Documentation: runtime/internal/atomic

     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  //go:build mips || mipsle
     6  // +build mips mipsle
     7  
     8  // Export some functions via linkname to assembly in sync/atomic.
     9  //go:linkname Xadd64
    10  //go:linkname Xchg64
    11  //go:linkname Cas64
    12  //go:linkname Load64
    13  //go:linkname Store64
    14  
    15  package atomic
    16  
    17  import (
    18  	"internal/cpu"
    19  	"unsafe"
    20  )
    21  
    22  // TODO implement lock striping
    23  var lock struct {
    24  	state uint32
    25  	pad   [cpu.CacheLinePadSize - 4]byte
    26  }
    27  
    28  //go:noescape
    29  func spinLock(state *uint32)
    30  
    31  //go:noescape
    32  func spinUnlock(state *uint32)
    33  
    34  //go:nosplit
    35  func lockAndCheck(addr *uint64) {
    36  	// ensure 8-byte alignment
    37  	if uintptr(unsafe.Pointer(addr))&7 != 0 {
    38  		panicUnaligned()
    39  	}
    40  	// force dereference before taking lock
    41  	_ = *addr
    42  
    43  	spinLock(&lock.state)
    44  }
    45  
    46  //go:nosplit
    47  func unlock() {
    48  	spinUnlock(&lock.state)
    49  }
    50  
    51  //go:nosplit
    52  func unlockNoFence() {
    53  	lock.state = 0
    54  }
    55  
    56  //go:nosplit
    57  func Xadd64(addr *uint64, delta int64) (new uint64) {
    58  	lockAndCheck(addr)
    59  
    60  	new = *addr + uint64(delta)
    61  	*addr = new
    62  
    63  	unlock()
    64  	return
    65  }
    66  
    67  //go:nosplit
    68  func Xchg64(addr *uint64, new uint64) (old uint64) {
    69  	lockAndCheck(addr)
    70  
    71  	old = *addr
    72  	*addr = new
    73  
    74  	unlock()
    75  	return
    76  }
    77  
    78  //go:nosplit
    79  func Cas64(addr *uint64, old, new uint64) (swapped bool) {
    80  	lockAndCheck(addr)
    81  
    82  	if (*addr) == old {
    83  		*addr = new
    84  		unlock()
    85  		return true
    86  	}
    87  
    88  	unlockNoFence()
    89  	return false
    90  }
    91  
    92  //go:nosplit
    93  func Load64(addr *uint64) (val uint64) {
    94  	lockAndCheck(addr)
    95  
    96  	val = *addr
    97  
    98  	unlock()
    99  	return
   100  }
   101  
   102  //go:nosplit
   103  func Store64(addr *uint64, val uint64) {
   104  	lockAndCheck(addr)
   105  
   106  	*addr = val
   107  
   108  	unlock()
   109  	return
   110  }
   111  
   112  //go:noescape
   113  func Xadd(ptr *uint32, delta int32) uint32
   114  
   115  //go:noescape
   116  func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
   117  
   118  //go:noescape
   119  func Xchg(ptr *uint32, new uint32) uint32
   120  
   121  //go:noescape
   122  func Xchguintptr(ptr *uintptr, new uintptr) uintptr
   123  
   124  //go:noescape
   125  func Load(ptr *uint32) uint32
   126  
   127  //go:noescape
   128  func Load8(ptr *uint8) uint8
   129  
   130  // NO go:noescape annotation; *ptr escapes if result escapes (#31525)
   131  func Loadp(ptr unsafe.Pointer) unsafe.Pointer
   132  
   133  //go:noescape
   134  func LoadAcq(ptr *uint32) uint32
   135  
   136  //go:noescape
   137  func LoadAcquintptr(ptr *uintptr) uintptr
   138  
   139  //go:noescape
   140  func And8(ptr *uint8, val uint8)
   141  
   142  //go:noescape
   143  func Or8(ptr *uint8, val uint8)
   144  
   145  //go:noescape
   146  func And(ptr *uint32, val uint32)
   147  
   148  //go:noescape
   149  func Or(ptr *uint32, val uint32)
   150  
   151  //go:noescape
   152  func Store(ptr *uint32, val uint32)
   153  
   154  //go:noescape
   155  func Store8(ptr *uint8, val uint8)
   156  
   157  // NO go:noescape annotation; see atomic_pointer.go.
   158  func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
   159  
   160  //go:noescape
   161  func StoreRel(ptr *uint32, val uint32)
   162  
   163  //go:noescape
   164  func StoreReluintptr(ptr *uintptr, val uintptr)
   165  
   166  //go:noescape
   167  func CasRel(addr *uint32, old, new uint32) bool
   168  

View as plain text