OxL Reference

module std.stm

std.stm — software transactional memory (§8.9, D-7521..D-7529).

oxl
static A: TVar<i32> = TVar(100)
static B: TVar<i32> = TVar(0)
fn transfer(amt: i32) {
  atomic {
    let a = A.get()
    check(a >= amt)          // false: wait until A (or another TVar read so far) changes, then run the block again
    A.set(a - amt)
    B.update(x => x + amt)
  }
}

atomic { … } runs its block as one serializable transaction: it sees a consistent snapshot of every TVar it reads and its writes become visible all at once at the end; when another transaction changed something it read, the block runs again from the start (so it must be pure: no io/net/time/db, which the compiler checks, atomic-effects). A panic or the cancellation of the task discards the writes. atomic blocks nest: the inner one is part of the outer transaction. A TVar operation outside atomic is a one-operation transaction; check outside it panics. Runtime: runtime/src/sched/stm.cpp.

Example:

oxl✓ checked in CI
use std.stm { TVar }

fn main() io {
  let counter = TVar<i64>.new(0)
  atomic {
    counter.set(counter.get() + 1)
  }
  print("{atomic { counter.get() }}")
}
Output
1

Types

data TVarA transactional variable holding a T.

Functions

checkInside atomic { }

See also