...

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

     1	// Copyright 2018 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	// TODO(neelance): implement with actual atomic operations as soon as threads are available
     6	// See https://github.com/WebAssembly/design/issues/1073
     7	
     8	// Export some functions via linkname to assembly in sync/atomic.
     9	//go:linkname Load
    10	//go:linkname Loadp
    11	//go:linkname Load64
    12	//go:linkname Loaduintptr
    13	//go:linkname Xadd
    14	//go:linkname Xadd64
    15	//go:linkname Xadduintptr
    16	//go:linkname Xchg
    17	//go:linkname Xchg64
    18	//go:linkname Xchguintptr
    19	//go:linkname Cas
    20	//go:linkname Cas64
    21	//go:linkname Casuintptr
    22	//go:linkname Store
    23	//go:linkname Store64
    24	//go:linkname Storeuintptr
    25	
    26	package atomic
    27	
    28	import "unsafe"
    29	
    30	//go:nosplit
    31	//go:noinline
    32	func Load(ptr *uint32) uint32 {
    33		return *ptr
    34	}
    35	
    36	//go:nosplit
    37	//go:noinline
    38	func Loadp(ptr unsafe.Pointer) unsafe.Pointer {
    39		return *(*unsafe.Pointer)(ptr)
    40	}
    41	
    42	//go:nosplit
    43	//go:noinline
    44	func LoadAcq(ptr *uint32) uint32 {
    45		return *ptr
    46	}
    47	
    48	//go:nosplit
    49	//go:noinline
    50	func Load8(ptr *uint8) uint8 {
    51		return *ptr
    52	}
    53	
    54	//go:nosplit
    55	//go:noinline
    56	func Load64(ptr *uint64) uint64 {
    57		return *ptr
    58	}
    59	
    60	//go:nosplit
    61	//go:noinline
    62	func Xadd(ptr *uint32, delta int32) uint32 {
    63		new := *ptr + uint32(delta)
    64		*ptr = new
    65		return new
    66	}
    67	
    68	//go:nosplit
    69	//go:noinline
    70	func Xadd64(ptr *uint64, delta int64) uint64 {
    71		new := *ptr + uint64(delta)
    72		*ptr = new
    73		return new
    74	}
    75	
    76	//go:nosplit
    77	//go:noinline
    78	func Xadduintptr(ptr *uintptr, delta uintptr) uintptr {
    79		new := *ptr + delta
    80		*ptr = new
    81		return new
    82	}
    83	
    84	//go:nosplit
    85	//go:noinline
    86	func Xchg(ptr *uint32, new uint32) uint32 {
    87		old := *ptr
    88		*ptr = new
    89		return old
    90	}
    91	
    92	//go:nosplit
    93	//go:noinline
    94	func Xchg64(ptr *uint64, new uint64) uint64 {
    95		old := *ptr
    96		*ptr = new
    97		return old
    98	}
    99	
   100	//go:nosplit
   101	//go:noinline
   102	func Xchguintptr(ptr *uintptr, new uintptr) uintptr {
   103		old := *ptr
   104		*ptr = new
   105		return old
   106	}
   107	
   108	//go:nosplit
   109	//go:noinline
   110	func And8(ptr *uint8, val uint8) {
   111		*ptr = *ptr & val
   112	}
   113	
   114	//go:nosplit
   115	//go:noinline
   116	func Or8(ptr *uint8, val uint8) {
   117		*ptr = *ptr | val
   118	}
   119	
   120	// NOTE: Do not add atomicxor8 (XOR is not idempotent).
   121	
   122	//go:nosplit
   123	//go:noinline
   124	func Cas64(ptr *uint64, old, new uint64) bool {
   125		if *ptr == old {
   126			*ptr = new
   127			return true
   128		}
   129		return false
   130	}
   131	
   132	//go:nosplit
   133	//go:noinline
   134	func Store(ptr *uint32, val uint32) {
   135		*ptr = val
   136	}
   137	
   138	//go:nosplit
   139	//go:noinline
   140	func StoreRel(ptr *uint32, val uint32) {
   141		*ptr = val
   142	}
   143	
   144	//go:nosplit
   145	//go:noinline
   146	func Store64(ptr *uint64, val uint64) {
   147		*ptr = val
   148	}
   149	
   150	//go:notinheap
   151	type noWB struct{}
   152	
   153	//go:noinline
   154	//go:nosplit
   155	func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) {
   156		*(**noWB)(ptr) = (*noWB)(val)
   157	}
   158	
   159	//go:nosplit
   160	//go:noinline
   161	func Cas(ptr *uint32, old, new uint32) bool {
   162		if *ptr == old {
   163			*ptr = new
   164			return true
   165		}
   166		return false
   167	}
   168	
   169	//go:nosplit
   170	//go:noinline
   171	func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
   172		if *ptr == old {
   173			*ptr = new
   174			return true
   175		}
   176		return false
   177	}
   178	
   179	//go:nosplit
   180	//go:noinline
   181	func Casuintptr(ptr *uintptr, old, new uintptr) bool {
   182		if *ptr == old {
   183			*ptr = new
   184			return true
   185		}
   186		return false
   187	}
   188	
   189	//go:nosplit
   190	//go:noinline
   191	func CasRel(ptr *uint32, old, new uint32) bool {
   192		if *ptr == old {
   193			*ptr = new
   194			return true
   195		}
   196		return false
   197	}
   198	
   199	//go:nosplit
   200	//go:noinline
   201	func Storeuintptr(ptr *uintptr, new uintptr) {
   202		*ptr = new
   203	}
   204	
   205	//go:nosplit
   206	//go:noinline
   207	func Loaduintptr(ptr *uintptr) uintptr {
   208		return *ptr
   209	}
   210	
   211	//go:nosplit
   212	//go:noinline
   213	func Loaduint(ptr *uint) uint {
   214		return *ptr
   215	}
   216	
   217	//go:nosplit
   218	//go:noinline
   219	func Loadint64(ptr *int64) int64 {
   220		return *ptr
   221	}
   222	
   223	//go:nosplit
   224	//go:noinline
   225	func Xaddint64(ptr *int64, delta int64) int64 {
   226		new := *ptr + delta
   227		*ptr = new
   228		return new
   229	}
   230	

View as plain text