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