Low-level atomic operations for V with explicit i386 support (MMX required on i386).
Native atomic primitives for V implemented with inline assembly, without relying on C FFI.
This repository is an experiment in providing low-level atomic operations directly in V, using V’s inline assembly support.
At the moment, all operations provide sequentially consistent semantics.
You need a working V toolchain. See the official documentation if you do not have it installed yet.
You can install this repository directly using V’s package management:
v install --git https://github.com/RbPyer/v-atomicsIn the current V ecosystem, atomic operations are implemented via calls into C. While this approach works, it introduces an additional dependency on the C toolchain and headers and limits control over the exact machine instructions being emitted.
v-atomics explores an alternative: native atomic operations implemented directly in V, using architecture-specific inline assembly and explicit semantics.
The current focus of this project is:
- correctness of basic atomic primitives;
- predictable and inspectable code generation;
- sequentially consistent behavior for all operations.
In future versions, the set of supported atomic operations will be expanded, and additional memory orderings will be introduced.
- atomic operations on integer types implemented in V with inline assembly;
- architecture-specific implementations (per-platform
atomics.<arch>.vfiles); - sequential consistency for all exposed operations.
All operations in this library are intended to be sequentially consistent:
- operations appear to be globally ordered;
- no weaker semantics (relaxed, acquire, release) are currently implemented;
- when weaker variants are added in the future, they will be explicitly named and documented.
See the examples directory for complete runnable examples.
import atomics
fn main() {
mut value := i32(0)
// Atomically store a value
atomics.store_i32(&value, 42)
// Atomically load the value
loaded := atomics.load_i32(&value)
// Atomic add: returns the new value after addition
new_value := atomics.add_i32(&value, 10)
// Atomic swap: returns the old value
old := atomics.swap_i32(&value, 100)
}import atomics
fn main() {
mut flag := u32(0)
// CAS: if flag == 0, set it to 1; returns true on success
if atomics.cas_u32(&flag, 0, 1) {
println('Successfully changed flag from 0 to 1')
}
}| Operation | i32 | i64 | u32 | u64 |
|---|---|---|---|---|
load_* |
yes | yes | yes | yes |
store_* |
yes | yes | yes | yes |
add_* |
yes | yes | yes | yes |
swap_* |
yes | yes | yes | yes |
cas_* |
yes | yes | yes | yes |