211 lines
3.0 KiB
V
211 lines
3.0 KiB
V
// vtest build: !(macos || windows)
|
|
|
|
module atomics
|
|
|
|
fn test_add_u32_basic() {
|
|
mut x := u32(0)
|
|
for _ in 0 .. 1000 {
|
|
add_u32(&x, 1)
|
|
}
|
|
assert x == 1000
|
|
}
|
|
|
|
fn test_add_u32_wraparound() {
|
|
mut x := u32(0xffffffff)
|
|
add_u32(&x, 1)
|
|
assert x == 0
|
|
}
|
|
|
|
fn test_add_u32_large() {
|
|
mut x := u32(10)
|
|
r := add_u32(&x, 1000)
|
|
assert r == 1010
|
|
assert x == 1010
|
|
}
|
|
|
|
fn test_swap_u32_basic() {
|
|
mut x := u32(123)
|
|
old := swap_u32(&x, 999)
|
|
assert old == 123
|
|
assert x == 999
|
|
}
|
|
|
|
fn test_swap_u32_same() {
|
|
mut x := u32(777)
|
|
old := swap_u32(&x, 777)
|
|
assert old == 777
|
|
assert x == 777
|
|
}
|
|
|
|
fn test_store_u32_basic() {
|
|
mut x := u32(1)
|
|
store_u32(&x, 555)
|
|
assert x == 555
|
|
}
|
|
|
|
fn test_load_u32_basic() {
|
|
mut x := u32(888)
|
|
assert load_u32(&x) == 888
|
|
}
|
|
|
|
fn test_cas_u32_basic() {
|
|
mut x := u32(10)
|
|
assert cas_u32(&x, 10, 50)
|
|
assert x == 50
|
|
}
|
|
|
|
fn test_cas_u32_fail() {
|
|
mut x := u32(10)
|
|
assert !cas_u32(&x, 5, 999)
|
|
assert x == 10
|
|
}
|
|
|
|
fn test_cas_u32_nochange_on_fail() {
|
|
mut x := u32(777)
|
|
cas_u32(&x, 5, 9)
|
|
assert x == 777
|
|
}
|
|
|
|
fn test_cas_u32_boundary() {
|
|
mut x := u32(0xffffffff)
|
|
assert cas_u32(&x, 0xffffffff, 0)
|
|
assert x == 0
|
|
}
|
|
|
|
fn test_add_u32_concurrent() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
|
|
for _ in 0 .. 8 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 100_000 {
|
|
add_u32(px, 1)
|
|
}
|
|
}(&x)
|
|
}
|
|
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
|
|
assert x == 800_000
|
|
}
|
|
|
|
fn test_swap_u32_concurrent() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
|
|
for _ in 0 .. 8 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 50_000 {
|
|
swap_u32(px, 123)
|
|
}
|
|
}(&x)
|
|
}
|
|
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
|
|
assert x == 123
|
|
}
|
|
|
|
fn test_cas_u32_concurrent_inc() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
|
|
for _ in 0 .. 8 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 50_000 {
|
|
for {
|
|
old := load_u32(px)
|
|
if cas_u32(px, old, old + 1) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}(&x)
|
|
}
|
|
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
|
|
assert x == 400_000
|
|
}
|
|
|
|
fn test_cas_u32_contended_flip() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
|
|
for _ in 0 .. 4 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 200_000 {
|
|
cas_u32(px, 0, 1)
|
|
cas_u32(px, 1, 0)
|
|
}
|
|
}(&x)
|
|
}
|
|
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
|
|
assert x == 0 || x == 1
|
|
}
|
|
|
|
fn test_load_store_u32_concurrent() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
|
|
for i in 0 .. 8 {
|
|
threads << spawn fn (px &u32, id int) {
|
|
for _ in 0 .. 50_000 {
|
|
if id % 2 == 0 {
|
|
store_u32(px, 1)
|
|
} else {
|
|
_ = load_u32(px)
|
|
}
|
|
}
|
|
}(&x, i)
|
|
}
|
|
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
|
|
assert x == 1
|
|
}
|
|
|
|
fn test_and_u32_concurrent() {
|
|
mut x := u32(0xffffffff)
|
|
mut threads := []thread{}
|
|
for _ in 0 .. 8 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 100_000 {
|
|
and_u32(px, 0x0f0f0f0f)
|
|
}
|
|
}(&x)
|
|
}
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
assert x == 0x0f0f0f0f
|
|
}
|
|
|
|
fn test_or_u32_concurrent() {
|
|
mut x := u32(0)
|
|
mut threads := []thread{}
|
|
for _ in 0 .. 8 {
|
|
threads << spawn fn (px &u32) {
|
|
for _ in 0 .. 100_000 {
|
|
or_u32(px, 0xdeadbeef)
|
|
}
|
|
}(&x)
|
|
}
|
|
for t in threads {
|
|
t.wait()
|
|
}
|
|
assert x == u32(0xdeadbeef)
|
|
}
|