github.com/primecitizens/pcz/std@v0.2.1/core/atomic/atomic_mipsx.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2016 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  //go:build mips || mipsle
     9  
    10  package atomic
    11  
    12  import (
    13  	"unsafe"
    14  
    15  	"github.com/primecitizens/pcz/std/core/cpu"
    16  )
    17  
    18  // TODO implement lock striping
    19  var lock struct {
    20  	state uint32
    21  	pad   [cpu.CacheLinePadSize - 4]byte
    22  }
    23  
    24  //go:noescape
    25  func spinLock(state *uint32)
    26  
    27  //go:noescape
    28  func spinUnlock(state *uint32)
    29  
    30  //go:nosplit
    31  func lockAndCheck(addr *uint64) {
    32  	// ensure 8-byte alignment
    33  	if uintptr(unsafe.Pointer(addr))&7 != 0 {
    34  		panicUnaligned()
    35  	}
    36  	// force dereference before taking lock
    37  	_ = *addr
    38  
    39  	spinLock(&lock.state)
    40  }
    41  
    42  //go:nosplit
    43  func unlock() {
    44  	spinUnlock(&lock.state)
    45  }
    46  
    47  //go:nosplit
    48  func unlockNoFence() {
    49  	lock.state = 0
    50  }
    51  
    52  //
    53  // Store
    54  //
    55  
    56  //go:noescape
    57  func Store8(ptr *uint8, val uint8)
    58  
    59  //go:noescape
    60  func Store32(ptr *uint32, val uint32)
    61  
    62  //go:nosplit
    63  func Store64(addr *uint64, val uint64) {
    64  	lockAndCheck(addr)
    65  
    66  	*addr = val
    67  
    68  	unlock()
    69  	return
    70  }
    71  
    72  // NO go:noescape annotation; see atomic_pointer.go.
    73  func StorePointer(ptr unsafe.Pointer, val unsafe.Pointer)
    74  
    75  //
    76  // StoreRel
    77  //
    78  
    79  //go:noescape
    80  func StoreRel32(ptr *uint32, val uint32)
    81  
    82  //go:noescape
    83  func StoreRelUintptr(ptr *uintptr, val uintptr)
    84  
    85  //
    86  // Load
    87  //
    88  
    89  //go:noescape
    90  func Load8(ptr *uint8) uint8
    91  
    92  //go:noescape
    93  func Load32(ptr *uint32) uint32
    94  
    95  //go:nosplit
    96  func Load64(addr *uint64) (val uint64) {
    97  	lockAndCheck(addr)
    98  
    99  	val = *addr
   100  
   101  	unlock()
   102  	return
   103  }
   104  
   105  // NO go:noescape annotation; *ptr escapes if result escapes (#31525)
   106  func LoadPointer(ptr unsafe.Pointer) unsafe.Pointer
   107  
   108  // LoadAcq
   109  
   110  //go:noescape
   111  func LoadAcq32(ptr *uint32) uint32
   112  
   113  //go:noescape
   114  func LoadAcqUintptr(ptr *uintptr) uintptr
   115  
   116  //
   117  // Swap
   118  //
   119  
   120  //go:noescape
   121  func Swap32(ptr *uint32, new uint32) uint32
   122  
   123  //go:nosplit
   124  func Swap64(addr *uint64, new uint64) (old uint64) {
   125  	lockAndCheck(addr)
   126  
   127  	old = *addr
   128  	*addr = new
   129  
   130  	unlock()
   131  	return
   132  }
   133  
   134  //go:noescape
   135  func SwapUintptr(ptr *uintptr, new uintptr) uintptr
   136  
   137  //
   138  // Add
   139  //
   140  
   141  //go:noescape
   142  func Add32(ptr *uint32, delta int32) uint32
   143  
   144  //go:nosplit
   145  func Add64(addr *uint64, delta int64) (new uint64) {
   146  	lockAndCheck(addr)
   147  
   148  	new = *addr + uint64(delta)
   149  	*addr = new
   150  
   151  	unlock()
   152  	return
   153  }
   154  
   155  //go:noescape
   156  func AddUintptr(ptr *uintptr, delta uintptr) uintptr
   157  
   158  //
   159  // Compare and swap
   160  //
   161  
   162  //go:nosplit
   163  func Cas64(addr *uint64, old, new uint64) (swapped bool) {
   164  	lockAndCheck(addr)
   165  
   166  	if (*addr) == old {
   167  		*addr = new
   168  		unlock()
   169  		return true
   170  	}
   171  
   172  	unlockNoFence()
   173  	return false
   174  }
   175  
   176  //
   177  // bitwise
   178  //
   179  
   180  //go:noescape
   181  func And8(ptr *uint8, val uint8)
   182  
   183  //go:noescape
   184  func And32(ptr *uint32, val uint32)
   185  
   186  //go:noescape
   187  func Or8(ptr *uint8, val uint8)
   188  
   189  //go:noescape
   190  func Or32(ptr *uint32, val uint32)
   191  
   192  //
   193  // CasRel
   194  //
   195  
   196  //go:noescape
   197  func CasRel32(addr *uint32, old, new uint32) bool