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

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2018 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  // TODO(neelance): implement with actual atomic operations as soon as threads are available
     9  // See https://github.com/WebAssembly/design/issues/1073
    10  
    11  //go:build wasm
    12  
    13  package atomic
    14  
    15  import "unsafe"
    16  
    17  //go:nosplit
    18  //go:noinline
    19  func PublicationBarrier() {}
    20  
    21  //
    22  // Store
    23  //
    24  
    25  //go:nosplit
    26  //go:noinline
    27  func Store8(ptr *uint8, val uint8) {
    28  	*ptr = val
    29  }
    30  
    31  //go:nosplit
    32  //go:noinline
    33  func Store32(ptr *uint32, val uint32) {
    34  	*ptr = val
    35  }
    36  
    37  //go:nosplit
    38  //go:noinline
    39  func Store64(ptr *uint64, val uint64) {
    40  	*ptr = val
    41  }
    42  
    43  //go:nosplit
    44  //go:noinline
    45  func StoreUintptr(ptr *uintptr, new uintptr) {
    46  	*ptr = new
    47  }
    48  
    49  // StorePointer performs *ptr = val atomically and without a write
    50  // barrier.
    51  //
    52  // NO go:noescape annotation; see atomic_pointer.go.
    53  func StorePointer(ptr unsafe.Pointer, val unsafe.Pointer)
    54  
    55  //go:nosplit
    56  //go:noinline
    57  func StoreInt32(ptr *int32, new int32) {
    58  	*ptr = new
    59  }
    60  
    61  //go:nosplit
    62  //go:noinline
    63  func StoreInt64(ptr *int64, new int64) {
    64  	*ptr = new
    65  }
    66  
    67  //
    68  // StoreRel
    69  //
    70  
    71  //go:nosplit
    72  //go:noinline
    73  func StoreRel32(ptr *uint32, val uint32) {
    74  	*ptr = val
    75  }
    76  
    77  //go:nosplit
    78  //go:noinline
    79  func StoreRel64(ptr *uint64, val uint64) {
    80  	*ptr = val
    81  }
    82  
    83  //go:nosplit
    84  //go:noinline
    85  func StoreRelUintptr(ptr *uintptr, val uintptr) {
    86  	*ptr = val
    87  }
    88  
    89  //
    90  // Load
    91  //
    92  
    93  //go:nosplit
    94  //go:noinline
    95  func Load8(ptr *uint8) uint8 {
    96  	return *ptr
    97  }
    98  
    99  //go:nosplit
   100  //go:noinline
   101  func Load32(ptr *uint32) uint32 {
   102  	return *ptr
   103  }
   104  
   105  //go:nosplit
   106  //go:noinline
   107  func Load64(ptr *uint64) uint64 {
   108  	return *ptr
   109  }
   110  
   111  //go:nosplit
   112  //go:noinline
   113  func LoadUint(ptr *uint) uint {
   114  	return *ptr
   115  }
   116  
   117  //go:nosplit
   118  //go:noinline
   119  func LoadUintptr(ptr *uintptr) uintptr {
   120  	return *ptr
   121  }
   122  
   123  //go:nosplit
   124  //go:noinline
   125  func LoadPointer(ptr unsafe.Pointer) unsafe.Pointer {
   126  	return *(*unsafe.Pointer)(ptr)
   127  }
   128  
   129  //go:nosplit
   130  //go:noinline
   131  func LoadInt32(ptr *int32) int32 {
   132  	return *ptr
   133  }
   134  
   135  //go:nosplit
   136  //go:noinline
   137  func LoadInt64(ptr *int64) int64 {
   138  	return *ptr
   139  }
   140  
   141  //
   142  // LoadAcq
   143  //
   144  
   145  //go:nosplit
   146  //go:noinline
   147  func LoadAcq32(ptr *uint32) uint32 {
   148  	return *ptr
   149  }
   150  
   151  //go:nosplit
   152  //go:noinline
   153  func LoadAcq64(ptr *uint64) uint64 {
   154  	return *ptr
   155  }
   156  
   157  //go:nosplit
   158  //go:noinline
   159  func LoadAcqUintptr(ptr *uintptr) uintptr {
   160  	return *ptr
   161  }
   162  
   163  //
   164  // bitwise
   165  //
   166  // NOTE: Do not add atomicxor8 (XOR is not idempotent).
   167  
   168  //go:nosplit
   169  //go:noinline
   170  func And8(ptr *uint8, val uint8) {
   171  	*ptr = *ptr & val
   172  }
   173  
   174  //go:nosplit
   175  //go:noinline
   176  func And32(ptr *uint32, val uint32) {
   177  	*ptr = *ptr & val
   178  }
   179  
   180  //go:nosplit
   181  //go:noinline
   182  func Or8(ptr *uint8, val uint8) {
   183  	*ptr = *ptr | val
   184  }
   185  
   186  //go:nosplit
   187  //go:noinline
   188  func Or32(ptr *uint32, val uint32) {
   189  	*ptr = *ptr | val
   190  }
   191  
   192  //
   193  // Swap
   194  //
   195  
   196  //go:nosplit
   197  //go:noinline
   198  func Swap32(ptr *uint32, new uint32) uint32 {
   199  	old := *ptr
   200  	*ptr = new
   201  	return old
   202  }
   203  
   204  //go:nosplit
   205  //go:noinline
   206  func Swap64(ptr *uint64, new uint64) uint64 {
   207  	old := *ptr
   208  	*ptr = new
   209  	return old
   210  }
   211  
   212  //go:nosplit
   213  //go:noinline
   214  func SwapUintptr(ptr *uintptr, new uintptr) uintptr {
   215  	old := *ptr
   216  	*ptr = new
   217  	return old
   218  }
   219  
   220  //go:nosplit
   221  //go:noinline
   222  func SwapInt32(ptr *int32, new int32) int32 {
   223  	old := *ptr
   224  	*ptr = new
   225  	return old
   226  }
   227  
   228  //go:nosplit
   229  //go:noinline
   230  func SwapInt64(ptr *int64, new int64) int64 {
   231  	old := *ptr
   232  	*ptr = new
   233  	return old
   234  }
   235  
   236  //
   237  // Add
   238  //
   239  
   240  //go:nosplit
   241  //go:noinline
   242  func Add32(ptr *uint32, delta int32) uint32 {
   243  	new := *ptr + uint32(delta)
   244  	*ptr = new
   245  	return new
   246  }
   247  
   248  //go:nosplit
   249  //go:noinline
   250  func Add64(ptr *uint64, delta int64) uint64 {
   251  	new := *ptr + uint64(delta)
   252  	*ptr = new
   253  	return new
   254  }
   255  
   256  //go:nosplit
   257  //go:noinline
   258  func AddUintptr(ptr *uintptr, delta uintptr) uintptr {
   259  	new := *ptr + delta
   260  	*ptr = new
   261  	return new
   262  }
   263  
   264  //go:nosplit
   265  //go:noinline
   266  func AddInt32(ptr *int32, delta int32) int32 {
   267  	new := *ptr + delta
   268  	*ptr = new
   269  	return new
   270  }
   271  
   272  //go:nosplit
   273  //go:noinline
   274  func AddInt64(ptr *int64, delta int64) int64 {
   275  	new := *ptr + delta
   276  	*ptr = new
   277  	return new
   278  }
   279  
   280  //
   281  // Compare and swap
   282  //
   283  
   284  //go:nosplit
   285  //go:noinline
   286  func Cas32(ptr *uint32, old, new uint32) bool {
   287  	if *ptr == old {
   288  		*ptr = new
   289  		return true
   290  	}
   291  	return false
   292  }
   293  
   294  //go:nosplit
   295  //go:noinline
   296  func Cas64(ptr *uint64, old, new uint64) bool {
   297  	if *ptr == old {
   298  		*ptr = new
   299  		return true
   300  	}
   301  	return false
   302  }
   303  
   304  //go:nosplit
   305  //go:noinline
   306  func CasUintptr(ptr *uintptr, old, new uintptr) bool {
   307  	if *ptr == old {
   308  		*ptr = new
   309  		return true
   310  	}
   311  	return false
   312  }
   313  
   314  //go:nosplit
   315  //go:noinline
   316  func CasUnsafePointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
   317  	if *ptr == old {
   318  		*ptr = new
   319  		return true
   320  	}
   321  	return false
   322  }
   323  
   324  //go:nosplit
   325  //go:noinline
   326  func CasInt32(ptr *int32, old, new int32) bool {
   327  	if *ptr == old {
   328  		*ptr = new
   329  		return true
   330  	}
   331  	return false
   332  }
   333  
   334  //go:nosplit
   335  //go:noinline
   336  func CasInt64(ptr *int64, old, new int64) bool {
   337  	if *ptr == old {
   338  		*ptr = new
   339  		return true
   340  	}
   341  	return false
   342  }
   343  
   344  //
   345  // CasRel
   346  //
   347  
   348  //go:nosplit
   349  //go:noinline
   350  func CasRel32(ptr *uint32, old, new uint32) bool {
   351  	if *ptr == old {
   352  		*ptr = new
   353  		return true
   354  	}
   355  	return false
   356  }