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

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

View as plain text