v2 / vlib / x / atomics / README.md
87 lines · 84 sloc · 3.11 KB · 1c4bb916e5cdf6aecbc6c6315f95453a9e8778f3
Raw

v-atomics

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.

Motivation

In 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. x.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:


Scope and Guarantees


Memory Model

All operations in this library are intended to be sequentially consistent:


Examples

See the examples directory for complete runnable examples.

Basic Usage

import x.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)
    _ = loaded
    _ = new_value
    _ = old
}

Compare-and-Swap (CAS)

import x.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')
    }
}

Bitwise Operations (AND / OR)

import x.atomics

fn main() {
    mut flags := u32(0xFF)
    // Atomically AND: clears lower nibble, returns old value
    old := atomics.and_u32(&flags, 0xF0)
    println('old: ${old}, new: ${flags}') // old: 255, new: 240
    // Atomically OR: sets a bit, returns old value
    prev := atomics.or_u32(&flags, 0x01)
    println('prev: ${prev}, new: ${flags}') // prev: 240, new: 241
}

Available Operations

| 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 | | and_* | yes | yes | yes | yes | | or_* | yes | yes | yes | yes |