mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
compiler: add support for atomic operations
This also implements DisableInterrupts/EnableInterrupts for RISC-V, as those operations were needed to implement a few libcalls.
This commit is contained in:
committed by
Ron Evans
parent
734613c20e
commit
fed433c046
Vendored
+95
@@ -0,0 +1,95 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
i32 := int32(-5)
|
||||
println("AddInt32:", atomic.AddInt32(&i32, 8), i32)
|
||||
|
||||
i64 := int64(-5)
|
||||
println("AddInt64:", atomic.AddInt64(&i64, 8), i64)
|
||||
|
||||
u32 := uint32(5)
|
||||
println("AddUint32:", atomic.AddUint32(&u32, 8), u32)
|
||||
|
||||
u64 := uint64(5)
|
||||
println("AddUint64:", atomic.AddUint64(&u64, 8), u64)
|
||||
|
||||
uptr := uintptr(5)
|
||||
println("AddUintptr:", uint64(atomic.AddUintptr(&uptr, 8)), uint64(uptr))
|
||||
|
||||
println("SwapInt32:", atomic.SwapInt32(&i32, 33), i32)
|
||||
println("SwapInt64:", atomic.SwapInt64(&i64, 33), i64)
|
||||
println("SwapUint32:", atomic.SwapUint32(&u32, 33), u32)
|
||||
println("SwapUint64:", atomic.SwapUint64(&u64, 33), u64)
|
||||
println("SwapUintptr:", uint64(atomic.SwapUintptr(&uptr, 33)), uint64(uptr))
|
||||
ptr := unsafe.Pointer(&i32)
|
||||
println("SwapPointer:", atomic.SwapPointer(&ptr, unsafe.Pointer(&u32)) == unsafe.Pointer(&i32), ptr == unsafe.Pointer(&u32))
|
||||
|
||||
i32 = int32(-5)
|
||||
println("CompareAndSwapInt32:", atomic.CompareAndSwapInt32(&i32, 5, 3), i32)
|
||||
println("CompareAndSwapInt32:", atomic.CompareAndSwapInt32(&i32, -5, 3), i32)
|
||||
|
||||
i64 = int64(-5)
|
||||
println("CompareAndSwapInt64:", atomic.CompareAndSwapInt64(&i64, 5, 3), i64)
|
||||
println("CompareAndSwapInt64:", atomic.CompareAndSwapInt64(&i64, -5, 3), i64)
|
||||
|
||||
u32 = uint32(5)
|
||||
println("CompareAndSwapUint32:", atomic.CompareAndSwapUint32(&u32, 4, 3), u32)
|
||||
println("CompareAndSwapUint32:", atomic.CompareAndSwapUint32(&u32, 5, 3), u32)
|
||||
|
||||
u64 = uint64(5)
|
||||
println("CompareAndSwapUint64:", atomic.CompareAndSwapUint64(&u64, 4, 3), u64)
|
||||
println("CompareAndSwapUint64:", atomic.CompareAndSwapUint64(&u64, 5, 3), u64)
|
||||
|
||||
uptr = uintptr(5)
|
||||
println("CompareAndSwapUintptr:", atomic.CompareAndSwapUintptr(&uptr, 4, 3), uint64(uptr))
|
||||
println("CompareAndSwapUintptr:", atomic.CompareAndSwapUintptr(&uptr, 5, 3), uint64(uptr))
|
||||
|
||||
ptr = unsafe.Pointer(&i32)
|
||||
println("CompareAndSwapPointer:", atomic.CompareAndSwapPointer(&ptr, unsafe.Pointer(&u32), unsafe.Pointer(&i64)), ptr == unsafe.Pointer(&i32))
|
||||
println("CompareAndSwapPointer:", atomic.CompareAndSwapPointer(&ptr, unsafe.Pointer(&i32), unsafe.Pointer(&i64)), ptr == unsafe.Pointer(&i64))
|
||||
|
||||
println("LoadInt32:", atomic.LoadInt32(&i32))
|
||||
println("LoadInt64:", atomic.LoadInt64(&i64))
|
||||
println("LoadUint32:", atomic.LoadUint32(&u32))
|
||||
println("LoadUint64:", atomic.LoadUint64(&u64))
|
||||
println("LoadUintptr:", uint64(atomic.LoadUintptr(&uptr)))
|
||||
println("LoadPointer:", atomic.LoadPointer(&ptr) == unsafe.Pointer(&i64))
|
||||
|
||||
atomic.StoreInt32(&i32, -20)
|
||||
println("StoreInt32:", i32)
|
||||
|
||||
atomic.StoreInt64(&i64, -20)
|
||||
println("StoreInt64:", i64)
|
||||
|
||||
atomic.StoreUint32(&u32, 20)
|
||||
println("StoreUint32:", u32)
|
||||
|
||||
atomic.StoreUint64(&u64, 20)
|
||||
println("StoreUint64:", u64)
|
||||
|
||||
atomic.StoreUintptr(&uptr, 20)
|
||||
println("StoreUintptr:", uint64(uptr))
|
||||
|
||||
atomic.StorePointer(&ptr, unsafe.Pointer(&uptr))
|
||||
println("StorePointer:", ptr == unsafe.Pointer(&uptr))
|
||||
|
||||
// test atomic.Value load/store operations
|
||||
testValue(int(3), int(-2))
|
||||
testValue("", "foobar", "baz")
|
||||
}
|
||||
|
||||
func testValue(values ...interface{}) {
|
||||
var av atomic.Value
|
||||
for _, val := range values {
|
||||
av.Store(val)
|
||||
loadedVal := av.Load()
|
||||
if loadedVal != val {
|
||||
println("val store/load didn't work, expected", val, "but got", loadedVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
AddInt32: 3 3
|
||||
AddInt64: 3 3
|
||||
AddUint32: 13 13
|
||||
AddUint64: 13 13
|
||||
AddUintptr: 13 13
|
||||
SwapInt32: 3 33
|
||||
SwapInt64: 3 33
|
||||
SwapUint32: 13 33
|
||||
SwapUint64: 13 33
|
||||
SwapUintptr: 13 33
|
||||
SwapPointer: true true
|
||||
CompareAndSwapInt32: false -5
|
||||
CompareAndSwapInt32: true 3
|
||||
CompareAndSwapInt64: false -5
|
||||
CompareAndSwapInt64: true 3
|
||||
CompareAndSwapUint32: false 5
|
||||
CompareAndSwapUint32: true 3
|
||||
CompareAndSwapUint64: false 5
|
||||
CompareAndSwapUint64: true 3
|
||||
CompareAndSwapUintptr: false 5
|
||||
CompareAndSwapUintptr: true 3
|
||||
CompareAndSwapPointer: false true
|
||||
CompareAndSwapPointer: true true
|
||||
LoadInt32: 3
|
||||
LoadInt64: 3
|
||||
LoadUint32: 3
|
||||
LoadUint64: 3
|
||||
LoadUintptr: 3
|
||||
LoadPointer: true
|
||||
StoreInt32: -20
|
||||
StoreInt64: -20
|
||||
StoreUint32: 20
|
||||
StoreUint64: 20
|
||||
StoreUintptr: 20
|
||||
StorePointer: true
|
||||
Reference in New Issue
Block a user