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