|
| 1 | +# v-atomics |
| 2 | + |
| 3 | +Low-level atomic operations for V with explicit i386 support (MMX required on i386). |
| 4 | + |
| 5 | +Native atomic primitives for V implemented with inline assembly, without relying on C FFI. |
| 6 | + |
| 7 | +This repository is an experiment in providing low-level atomic operations directly in V, |
| 8 | +using V's inline assembly support. |
| 9 | + |
| 10 | +At the moment, all operations provide sequentially consistent semantics. |
| 11 | + |
| 12 | +## Motivation |
| 13 | + |
| 14 | +In the current V ecosystem, atomic operations are implemented via calls into C. |
| 15 | + |
| 16 | +While this approach works, it introduces an additional dependency on the C toolchain |
| 17 | +and headers and limits control over the exact machine instructions being emitted. |
| 18 | + |
| 19 | +x.atomics explores an alternative: **native atomic operations implemented directly in V**, |
| 20 | +using architecture-specific inline assembly and explicit semantics. |
| 21 | + |
| 22 | +The current focus of this project is: |
| 23 | + |
| 24 | +- correctness of basic atomic primitives; |
| 25 | +- predictable and inspectable code generation; |
| 26 | +- sequentially consistent behavior for all operations. |
| 27 | + |
| 28 | +In future versions, the set of supported atomic operations will be expanded, |
| 29 | +and additional memory orderings will be introduced. |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## Scope and Guarantees |
| 34 | + |
| 35 | +- atomic operations on integer types implemented in V with inline assembly; |
| 36 | +- architecture-specific implementations (per-platform `atomics.<arch>.v` files); |
| 37 | +- **sequential consistency** for all exposed operations. |
| 38 | + |
| 39 | +--- |
| 40 | + |
| 41 | +## Memory Model |
| 42 | + |
| 43 | +All operations in this library are intended to be **sequentially consistent**: |
| 44 | + |
| 45 | +- operations appear to be globally ordered; |
| 46 | +- no weaker semantics (relaxed, acquire, release) are currently implemented; |
| 47 | +- when weaker variants are added in the future, they will be explicitly named and documented. |
| 48 | + |
| 49 | +--- |
| 50 | + |
| 51 | +## Examples |
| 52 | + |
| 53 | +See the [examples](examples/) directory for complete runnable examples. |
| 54 | + |
| 55 | +### Basic Usage |
| 56 | + |
| 57 | +```v |
| 58 | +import x.atomics |
| 59 | +
|
| 60 | +fn main() { |
| 61 | + mut value := i32(0) |
| 62 | +
|
| 63 | + // Atomically store a value |
| 64 | + atomics.store_i32(&value, 42) |
| 65 | +
|
| 66 | + // Atomically load the value |
| 67 | + loaded := atomics.load_i32(&value) |
| 68 | +
|
| 69 | + // Atomic add: returns the new value after addition |
| 70 | + new_value := atomics.add_i32(&value, 10) |
| 71 | +
|
| 72 | + // Atomic swap: returns the old value |
| 73 | + old := atomics.swap_i32(&value, 100) |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +### Compare-and-Swap (CAS) |
| 78 | + |
| 79 | +```v |
| 80 | +import x.atomics |
| 81 | +
|
| 82 | +fn main() { |
| 83 | + mut flag := u32(0) |
| 84 | +
|
| 85 | + // CAS: if flag == 0, set it to 1; returns true on success |
| 86 | + if atomics.cas_u32(&flag, 0, 1) { |
| 87 | + println('Successfully changed flag from 0 to 1') |
| 88 | + } |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +### Available Operations |
| 93 | + |
| 94 | +| Operation | i32 | i64 | u32 | u64 | |
| 95 | +|-----------|-----|-----|-----|-----| |
| 96 | +| `load_*` | yes | yes | yes | yes | |
| 97 | +| `store_*` | yes | yes | yes | yes | |
| 98 | +| `add_*` | yes | yes | yes | yes | |
| 99 | +| `swap_*` | yes | yes | yes | yes | |
| 100 | +| `cas_*` | yes | yes | yes | yes | |
0 commit comments