mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
runtime: add critical-section fallbacks for atomic And and Or
This commit is contained in:
@@ -105,6 +105,62 @@ func __atomic_add_fetch_2(ptr *uint16, value uint16, ordering uintptr) uint16 {
|
|||||||
return new
|
return new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicAnd16(ptr *uint16, value uint16) (old, new uint16) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old & value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_and_2
|
||||||
|
func __atomic_fetch_and_2(ptr *uint16, value uint16, ordering uintptr) uint16 {
|
||||||
|
old, _ := doAtomicAnd16(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_and_2
|
||||||
|
func __sync_fetch_and_and_2(ptr *uint16, value uint16) uint16 {
|
||||||
|
old, _ := doAtomicAnd16(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_and_fetch_2
|
||||||
|
func __atomic_and_fetch_2(ptr *uint16, value uint16, ordering uintptr) uint16 {
|
||||||
|
_, new := doAtomicAnd16(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicOr16(ptr *uint16, value uint16) (old, new uint16) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old | value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_or_2
|
||||||
|
func __atomic_fetch_or_2(ptr *uint16, value uint16, ordering uintptr) uint16 {
|
||||||
|
old, _ := doAtomicOr16(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_or_2
|
||||||
|
func __sync_fetch_and_or_2(ptr *uint16, value uint16) uint16 {
|
||||||
|
old, _ := doAtomicOr16(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_or_fetch_2
|
||||||
|
func __atomic_or_fetch_2(ptr *uint16, value uint16, ordering uintptr) uint16 {
|
||||||
|
_, new := doAtomicOr16(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
// 32-bit atomics.
|
// 32-bit atomics.
|
||||||
|
|
||||||
//export __atomic_load_4
|
//export __atomic_load_4
|
||||||
@@ -194,6 +250,62 @@ func __atomic_add_fetch_4(ptr *uint32, value uint32, ordering uintptr) uint32 {
|
|||||||
return new
|
return new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicAnd32(ptr *uint32, value uint32) (old, new uint32) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old & value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_and_4
|
||||||
|
func __atomic_fetch_and_4(ptr *uint32, value uint32, ordering uintptr) uint32 {
|
||||||
|
old, _ := doAtomicAnd32(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_and_4
|
||||||
|
func __sync_fetch_and_and_4(ptr *uint32, value uint32) uint32 {
|
||||||
|
old, _ := doAtomicAnd32(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_and_fetch_4
|
||||||
|
func __atomic_and_fetch_4(ptr *uint32, value uint32, ordering uintptr) uint32 {
|
||||||
|
_, new := doAtomicAnd32(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicOr32(ptr *uint32, value uint32) (old, new uint32) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old | value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_or_4
|
||||||
|
func __atomic_fetch_or_4(ptr *uint32, value uint32, ordering uintptr) uint32 {
|
||||||
|
old, _ := doAtomicOr32(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_or_4
|
||||||
|
func __sync_fetch_and_or_4(ptr *uint32, value uint32) uint32 {
|
||||||
|
old, _ := doAtomicOr32(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_or_fetch_4
|
||||||
|
func __atomic_or_fetch_4(ptr *uint32, value uint32, ordering uintptr) uint32 {
|
||||||
|
_, new := doAtomicOr32(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
// 64-bit atomics.
|
// 64-bit atomics.
|
||||||
|
|
||||||
//export __atomic_load_8
|
//export __atomic_load_8
|
||||||
@@ -282,3 +394,59 @@ func __atomic_add_fetch_8(ptr *uint64, value uint64, ordering uintptr) uint64 {
|
|||||||
_, new := doAtomicAdd64(ptr, value)
|
_, new := doAtomicAdd64(ptr, value)
|
||||||
return new
|
return new
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicAnd64(ptr *uint64, value uint64) (old, new uint64) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old & value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_and_8
|
||||||
|
func __atomic_fetch_and_8(ptr *uint64, value uint64, ordering uintptr) uint64 {
|
||||||
|
old, _ := doAtomicAnd64(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_and_8
|
||||||
|
func __sync_fetch_and_and_8(ptr *uint64, value uint64) uint64 {
|
||||||
|
old, _ := doAtomicAnd64(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_and_fetch_8
|
||||||
|
func __atomic_and_fetch_8(ptr *uint64, value uint64, ordering uintptr) uint64 {
|
||||||
|
_, new := doAtomicAnd64(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:inline
|
||||||
|
func doAtomicOr64(ptr *uint64, value uint64) (old, new uint64) {
|
||||||
|
mask := lockAtomics()
|
||||||
|
old = *ptr
|
||||||
|
new = old | value
|
||||||
|
*ptr = new
|
||||||
|
unlockAtomics(mask)
|
||||||
|
return old, new
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_fetch_or_8
|
||||||
|
func __atomic_fetch_or_8(ptr *uint64, value uint64, ordering uintptr) uint64 {
|
||||||
|
old, _ := doAtomicOr64(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __sync_fetch_and_or_8
|
||||||
|
func __sync_fetch_and_or_8(ptr *uint64, value uint64) uint64 {
|
||||||
|
old, _ := doAtomicOr64(ptr, value)
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
//export __atomic_or_fetch_8
|
||||||
|
func __atomic_or_fetch_8(ptr *uint64, value uint64, ordering uintptr) uint64 {
|
||||||
|
_, new := doAtomicOr64(ptr, value)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+24
@@ -23,6 +23,30 @@ func main() {
|
|||||||
uptr := uintptr(5)
|
uptr := uintptr(5)
|
||||||
println("AddUintptr:", uint64(atomic.AddUintptr(&uptr, 8)), uint64(uptr))
|
println("AddUintptr:", uint64(atomic.AddUintptr(&uptr, 8)), uint64(uptr))
|
||||||
|
|
||||||
|
i32 = 12
|
||||||
|
i64 = 12
|
||||||
|
u32 = 12
|
||||||
|
u64 = 12
|
||||||
|
uptr = 12
|
||||||
|
|
||||||
|
println("AndInt32:", atomic.AndInt32(&i32, 10), i32)
|
||||||
|
println("AndInt64:", atomic.AndInt64(&i64, 10), i64)
|
||||||
|
println("AndUint32:", atomic.AndUint32(&u32, 10), u32)
|
||||||
|
println("AndUint64:", atomic.AndUint64(&u64, 10), u64)
|
||||||
|
println("AndUintptr:", uint64(atomic.AndUintptr(&uptr, 10)), uint64(uptr))
|
||||||
|
|
||||||
|
println("OrInt32:", atomic.OrInt32(&i32, 3), i32)
|
||||||
|
println("OrInt64:", atomic.OrInt64(&i64, 3), i64)
|
||||||
|
println("OrUint32:", atomic.OrUint32(&u32, 3), u32)
|
||||||
|
println("OrUint64:", atomic.OrUint64(&u64, 3), u64)
|
||||||
|
println("OrUintptr:", uint64(atomic.OrUintptr(&uptr, 3)), uint64(uptr))
|
||||||
|
|
||||||
|
i32 = 3
|
||||||
|
i64 = 3
|
||||||
|
u32 = 13
|
||||||
|
u64 = 13
|
||||||
|
uptr = 13
|
||||||
|
|
||||||
println("SwapInt32:", atomic.SwapInt32(&i32, 33), i32)
|
println("SwapInt32:", atomic.SwapInt32(&i32, 33), i32)
|
||||||
println("SwapInt64:", atomic.SwapInt64(&i64, 33), i64)
|
println("SwapInt64:", atomic.SwapInt64(&i64, 33), i64)
|
||||||
println("SwapUint32:", atomic.SwapUint32(&u32, 33), u32)
|
println("SwapUint32:", atomic.SwapUint32(&u32, 33), u32)
|
||||||
|
|||||||
Vendored
+10
@@ -3,6 +3,16 @@ AddInt64: 3 3
|
|||||||
AddUint32: 13 13
|
AddUint32: 13 13
|
||||||
AddUint64: 13 13
|
AddUint64: 13 13
|
||||||
AddUintptr: 13 13
|
AddUintptr: 13 13
|
||||||
|
AndInt32: 12 8
|
||||||
|
AndInt64: 12 8
|
||||||
|
AndUint32: 12 8
|
||||||
|
AndUint64: 12 8
|
||||||
|
AndUintptr: 12 8
|
||||||
|
OrInt32: 8 11
|
||||||
|
OrInt64: 8 11
|
||||||
|
OrUint32: 8 11
|
||||||
|
OrUint64: 8 11
|
||||||
|
OrUintptr: 8 11
|
||||||
SwapInt32: 3 33
|
SwapInt32: 3 33
|
||||||
SwapInt64: 3 33
|
SwapInt64: 3 33
|
||||||
SwapUint32: 13 33
|
SwapUint32: 13 33
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ func __atomic_{{$opname}}_fetch_{{$bytes}}(ptr *{{$type}}, value {{$type}}, orde
|
|||||||
{{template "cas" .}}
|
{{template "cas" .}}
|
||||||
{{template "swap" .}}
|
{{template "swap" .}}
|
||||||
{{template "rmw" (tuple "add" . false "new = old + value")}}
|
{{template "rmw" (tuple "add" . false "new = old + value")}}
|
||||||
|
{{template "rmw" (tuple "and" . false "new = old & value")}}
|
||||||
|
{{template "rmw" (tuple "or" . false "new = old | value")}}
|
||||||
|
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{template "atomics" 2 -}}
|
{{template "atomics" 2 -}}
|
||||||
|
|||||||
Reference in New Issue
Block a user