diff --git a/vlib/sync/atomic2/atomic.v b/vlib/sync/atomic2/atomic.v index e427d8a79a..6727e54635 100644 --- a/vlib/sync/atomic2/atomic.v +++ b/vlib/sync/atomic2/atomic.v @@ -26,37 +26,48 @@ $if linux { #include -fn C.atomic_fetch_add_explicit(voidptr, i64) i64 -fn C.atomic_fetch_sub_explicit(voidptr, i64) i64 - -[typedef] -struct C.atomic_ullong { -} - -[typedef] -struct C.atomic_llong { -} - // add_u64 adds provided delta as an atomic operation pub fn add_u64(ptr &u64, delta int) bool { - res := C.atomic_fetch_add_explicit(&C.atomic_ullong(ptr), delta, C.NULL) + res := C.atomic_fetch_add_u64(ptr, delta) return res == 0 } // sub_u64 subtracts provided delta as an atomic operation pub fn sub_u64(ptr &u64, delta int) bool { - res := C.atomic_fetch_sub_explicit(&C.atomic_ullong(ptr), delta, C.NULL) + res := C.atomic_fetch_sub_u64(ptr, delta) return res == 0 } // add_i64 adds provided delta as an atomic operation pub fn add_i64(ptr &i64, delta int) bool { - res := C.atomic_fetch_add_explicit(&C.atomic_llong(ptr), delta, C.NULL) + res := C.atomic_fetch_add_u64(ptr, delta) return res == 0 } // add_i64 subtracts provided delta as an atomic operation pub fn sub_i64(ptr &i64, delta int) bool { - res := C.atomic_fetch_sub_explicit(&C.atomic_llong(ptr), delta, C.NULL) + res := C.atomic_fetch_sub_u64(ptr, delta) return res == 0 } + +// atomic store/load operations have to be used when there might be another concurrent access + +// atomicall set a value +pub fn store_u64(ptr &u64, val u64) { + C.atomic_store_u64(ptr, val) +} + +// atomicall get a value +pub fn load_u64(ptr &u64) u64 { + return C.atomic_load_u64(ptr) +} + +// atomicall set a value +pub fn store_i64(ptr &i64, val i64) { + C.atomic_store_u64(ptr, val) +} + +// atomicall get a value +pub fn load_i64(ptr &i64) i64 { + return i64(C.atomic_load_u64(ptr)) +} diff --git a/vlib/sync/atomic2/atomic_test.v b/vlib/sync/atomic2/atomic_test.v index e0f64727c5..ddd6e964f4 100644 --- a/vlib/sync/atomic2/atomic_test.v +++ b/vlib/sync/atomic2/atomic_test.v @@ -41,49 +41,51 @@ fn test_count_10_times_1_cycle_should_not_be_10_cycles_without_sync() { fn test_count_plus_one_u64() { mut c := u64(0) atomic2.add_u64(&c, 1) - assert c == 1 + assert atomic2.load_u64(&c) == 1 } fn test_count_plus_one_i64() { mut c := i64(0) atomic2.add_i64(&c, 1) - assert c == 1 + assert atomic2.load_i64(&c) == 1 } fn test_count_plus_greater_than_one_u64() { mut c := u64(0) atomic2.add_u64(&c, 10) - assert c == 10 + assert atomic2.load_u64(&c) == 10 } fn test_count_plus_greater_than_one_i64() { mut c := i64(0) atomic2.add_i64(&c, 10) - assert c == 10 + assert atomic2.load_i64(&c) == 10 } fn test_count_minus_one_u64() { mut c := u64(1) atomic2.sub_u64(&c, 1) - assert c == 0 + assert atomic2.load_u64(&c) == 0 } fn test_count_minus_one_i64() { mut c := i64(0) atomic2.sub_i64(&c, 1) - assert c == -1 + assert atomic2.load_i64(&c) == -1 } fn test_count_minus_greater_than_one_u64() { - mut c := u64(10) + mut c := u64(0) + atomic2.store_u64(&c, 10) atomic2.sub_u64(&c, 10) - assert c == 0 + assert atomic2.load_u64(&c) == 0 } fn test_count_minus_greater_than_one_i64() { - mut c := i64(10) + mut c := i64(0) + atomic2.store_i64(&c, 10) atomic2.sub_i64(&c, 20) - assert c == -10 + assert atomic2.load_i64(&c) == -10 } // count_one_cycle counts the common counter iterations_per_cycle times in thread-safe way