Source file src/internal/runtime/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  package atomic
     9  
    10  import "unsafe"
    11  
    12  //go:nosplit
    13  //go:noinline
    14  func Load(ptr *uint32) uint32 {
    15  	return *ptr
    16  }
    17  
    18  //go:nosplit
    19  //go:noinline
    20  func Loadp(ptr unsafe.Pointer) unsafe.Pointer {
    21  	return *(*unsafe.Pointer)(ptr)
    22  }
    23  
    24  //go:nosplit
    25  //go:noinline
    26  func LoadAcq(ptr *uint32) uint32 {
    27  	return *ptr
    28  }
    29  
    30  //go:nosplit
    31  //go:noinline
    32  func LoadAcq64(ptr *uint64) uint64 {
    33  	return *ptr
    34  }
    35  
    36  //go:nosplit
    37  //go:noinline
    38  func LoadAcquintptr(ptr *uintptr) uintptr {
    39  	return *ptr
    40  }
    41  
    42  //go:nosplit
    43  //go:noinline
    44  func Load8(ptr *uint8) uint8 {
    45  	return *ptr
    46  }
    47  
    48  //go:nosplit
    49  //go:noinline
    50  func Load64(ptr *uint64) uint64 {
    51  	return *ptr
    52  }
    53  
    54  //go:nosplit
    55  //go:noinline
    56  func Xadd(ptr *uint32, delta int32) uint32 {
    57  	new := *ptr + uint32(delta)
    58  	*ptr = new
    59  	return new
    60  }
    61  
    62  //go:nosplit
    63  //go:noinline
    64  func Xadd64(ptr *uint64, delta int64) uint64 {
    65  	new := *ptr + uint64(delta)
    66  	*ptr = new
    67  	return new
    68  }
    69  
    70  //go:nosplit
    71  //go:noinline
    72  func Xadduintptr(ptr *uintptr, delta uintptr) uintptr {
    73  	new := *ptr + delta
    74  	*ptr = new
    75  	return new
    76  }
    77  
    78  //go:nosplit
    79  //go:noinline
    80  func Xchg(ptr *uint32, new uint32) uint32 {
    81  	old := *ptr
    82  	*ptr = new
    83  	return old
    84  }
    85  
    86  //go:nosplit
    87  func Xchg8(addr *uint8, v uint8) uint8 {
    88  	return goXchg8(addr, v)
    89  }
    90  
    91  //go:nosplit
    92  //go:noinline
    93  func Xchg64(ptr *uint64, new uint64) uint64 {
    94  	old := *ptr
    95  	*ptr = new
    96  	return old
    97  }
    98  
    99  //go:nosplit
   100  //go:noinline
   101  func Xchgint32(ptr *int32, new int32) int32 {
   102  	old := *ptr
   103  	*ptr = new
   104  	return old
   105  }
   106  
   107  //go:nosplit
   108  //go:noinline
   109  func Xchgint64(ptr *int64, new int64) int64 {
   110  	old := *ptr
   111  	*ptr = new
   112  	return old
   113  }
   114  
   115  //go:nosplit
   116  //go:noinline
   117  func Xchguintptr(ptr *uintptr, new uintptr) uintptr {
   118  	old := *ptr
   119  	*ptr = new
   120  	return old
   121  }
   122  
   123  //go:nosplit
   124  //go:noinline
   125  func And8(ptr *uint8, val uint8) {
   126  	*ptr = *ptr & val
   127  }
   128  
   129  //go:nosplit
   130  //go:noinline
   131  func Or8(ptr *uint8, val uint8) {
   132  	*ptr = *ptr | val
   133  }
   134  
   135  // NOTE: Do not add atomicxor8 (XOR is not idempotent).
   136  
   137  //go:nosplit
   138  //go:noinline
   139  func And(ptr *uint32, val uint32) {
   140  	*ptr = *ptr & val
   141  }
   142  
   143  //go:nosplit
   144  //go:noinline
   145  func Or(ptr *uint32, val uint32) {
   146  	*ptr = *ptr | val
   147  }
   148  
   149  //go:nosplit
   150  //go:noinline
   151  func Cas64(ptr *uint64, old, new uint64) bool {
   152  	if *ptr == old {
   153  		*ptr = new
   154  		return true
   155  	}
   156  	return false
   157  }
   158  
   159  //go:nosplit
   160  //go:noinline
   161  func Store(ptr *uint32, val uint32) {
   162  	*ptr = val
   163  }
   164  
   165  //go:nosplit
   166  //go:noinline
   167  func StoreRel(ptr *uint32, val uint32) {
   168  	*ptr = val
   169  }
   170  
   171  //go:nosplit
   172  //go:noinline
   173  func StoreRel64(ptr *uint64, val uint64) {
   174  	*ptr = val
   175  }
   176  
   177  //go:nosplit
   178  //go:noinline
   179  func StoreReluintptr(ptr *uintptr, val uintptr) {
   180  	*ptr = val
   181  }
   182  
   183  //go:nosplit
   184  //go:noinline
   185  func Store8(ptr *uint8, val uint8) {
   186  	*ptr = val
   187  }
   188  
   189  //go:nosplit
   190  //go:noinline
   191  func Store64(ptr *uint64, val uint64) {
   192  	*ptr = val
   193  }
   194  
   195  // StorepNoWB performs *ptr = val atomically and without a write
   196  // barrier.
   197  //
   198  // NO go:noescape annotation; see atomic_pointer.go.
   199  func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
   200  
   201  //go:nosplit
   202  //go:noinline
   203  func Casint32(ptr *int32, old, new int32) bool {
   204  	if *ptr == old {
   205  		*ptr = new
   206  		return true
   207  	}
   208  	return false
   209  }
   210  
   211  //go:nosplit
   212  //go:noinline
   213  func Casint64(ptr *int64, old, new int64) bool {
   214  	if *ptr == old {
   215  		*ptr = new
   216  		return true
   217  	}
   218  	return false
   219  }
   220  
   221  //go:nosplit
   222  //go:noinline
   223  func Cas(ptr *uint32, old, new uint32) bool {
   224  	if *ptr == old {
   225  		*ptr = new
   226  		return true
   227  	}
   228  	return false
   229  }
   230  
   231  //go:nosplit
   232  //go:noinline
   233  func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
   234  	if *ptr == old {
   235  		*ptr = new
   236  		return true
   237  	}
   238  	return false
   239  }
   240  
   241  //go:nosplit
   242  //go:noinline
   243  func Casuintptr(ptr *uintptr, old, new uintptr) bool {
   244  	if *ptr == old {
   245  		*ptr = new
   246  		return true
   247  	}
   248  	return false
   249  }
   250  
   251  //go:nosplit
   252  //go:noinline
   253  func CasRel(ptr *uint32, old, new uint32) bool {
   254  	if *ptr == old {
   255  		*ptr = new
   256  		return true
   257  	}
   258  	return false
   259  }
   260  
   261  //go:nosplit
   262  //go:noinline
   263  func Storeint32(ptr *int32, new int32) {
   264  	*ptr = new
   265  }
   266  
   267  //go:nosplit
   268  //go:noinline
   269  func Storeint64(ptr *int64, new int64) {
   270  	*ptr = new
   271  }
   272  
   273  //go:nosplit
   274  //go:noinline
   275  func Storeuintptr(ptr *uintptr, new uintptr) {
   276  	*ptr = new
   277  }
   278  
   279  //go:nosplit
   280  //go:noinline
   281  func Loaduintptr(ptr *uintptr) uintptr {
   282  	return *ptr
   283  }
   284  
   285  //go:nosplit
   286  //go:noinline
   287  func Loaduint(ptr *uint) uint {
   288  	return *ptr
   289  }
   290  
   291  //go:nosplit
   292  //go:noinline
   293  func Loadint32(ptr *int32) int32 {
   294  	return *ptr
   295  }
   296  
   297  //go:nosplit
   298  //go:noinline
   299  func Loadint64(ptr *int64) int64 {
   300  	return *ptr
   301  }
   302  
   303  //go:nosplit
   304  //go:noinline
   305  func Xaddint32(ptr *int32, delta int32) int32 {
   306  	new := *ptr + delta
   307  	*ptr = new
   308  	return new
   309  }
   310  
   311  //go:nosplit
   312  //go:noinline
   313  func Xaddint64(ptr *int64, delta int64) int64 {
   314  	new := *ptr + delta
   315  	*ptr = new
   316  	return new
   317  }
   318  

View as plain text