...

Source file src/runtime/internal/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	// +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			addr = nil
    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 And8(ptr *uint8, val uint8)
   137	
   138	//go:noescape
   139	func Or8(ptr *uint8, val uint8)
   140	
   141	//go:noescape
   142	func Store(ptr *uint32, val uint32)
   143	
   144	// NO go:noescape annotation; see atomic_pointer.go.
   145	func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
   146	
   147	//go:noescape
   148	func StoreRel(ptr *uint32, val uint32)
   149	
   150	//go:noescape
   151	func CasRel(addr *uint32, old, new uint32) bool
   152	

View as plain text