Overview
Lock-free atomic references with hardware-accelerated integer operations for int, uint, long, and ulong.
(import (std atomic))
(def hits (make-atomic 0L))
(atomic-increment! hits) ; 1L
(atomic-add! hits 10L) ; 11L
(atomic-swap! hits 0L) ; 11L, hits reset to 0L
(def names (make-atomic (list "ada")))
(atomic-update! names (fun (ns) (Cons "bea" ns))) ; ("bea" "ada")
(Atomic T) holds a single value of type T. All operations are
atomic and memory-fenced; concurrent accesses across threads execute
sequentially without tearing.
Return values. atomic-swap! and
atomic-compare-and-swap! return the value prior to modification.
atomic-update!, atomic-increment!,
atomic-decrement!, atomic-add!, and atomic-sub!
return the updated value.
Equality comparisons. atomic-compare-and-swap! compares
the current value against an expected value. Reference types (records,
lists, strings) compare by reference identity (eq?). Value types
(structs, Option, primitive integers) compare by value.
Reference vs content safety. Atomicity applies strictly to the
stored reference or struct value itself. Internal mutations to mutable
objects referenced by the cell (such as arrays or mutable vectors) are not
synchronized. Use persistent structures updated via atomic-update!
for thread-safe compound state.
Integer operations. The AtomicInteger trait provides
atomic-increment!, atomic-decrement!, atomic-add!,
and atomic-sub!. Implementations for int, uint,
long, and ulong delegate directly to
System.Threading.Interlocked. Operations wrap on overflow (two’s
complement arithmetic). Using integer operations on unsupported types
produces compile errors.
Integer width. Width is determined by type inference or literal
suffixes. Use 0L or 0UL, or explicit type annotations like
(: hits (Atomic ulong)), to avoid overflow on large counters.
See also: make-atomic, atomic-update!, atomic-compare-and-swap!, AtomicInteger
Reference
Types
Atomic
type alias ↑ Types
Thread-safe atomic reference cell holding a value of type %a.
%a- The type of the contained value.
See also: make-atomic, atomic-ref, AtomicInteger
AtomicInteger
trait ↑ Types
Trait providing atomic arithmetic operations (increment, decrement, add, subtract).
%a- The integer type in the atomic cell.
Implemented for int, uint, long, and ulong via
direct calls to System.Threading.Interlocked.
Custom types may implement this trait using atomic-update!.
Implementations must uphold these invariants:
- Operations must execute atomically.
- Operations must return the updated value.
- Built-in integer operations wrap on overflow using two’s complement arithmetic.
(type (: Score (Struct (: points int))))
(impl (AtomicInteger Score)
(defun (atomic-increment! a) (atomic-add! a (Score (points 1))))
(defun (atomic-decrement! a) (atomic-sub! a (Score (points 1))))
(defun (atomic-add! a n)
(atomic-update! a (fun (s) (Score (points (+ (.points s) (.points n)))))))
(defun (atomic-sub! a n)
(atomic-update! a (fun (s) (Score (points (- (.points s) (.points n))))))))
See also: atomic-increment!, atomic-add!, atomic-update!
Functions
make-atomic
function ↑ Functions
(: make-atomic (-> %a (Atomic %a)))
Creates a new atomic cell initialized with a value.
value- Initial value stored in the cell.
- returns
- A new atomic reference cell.
(make-atomic 0) ; an (Atomic int)
(make-atomic 0L) ; an (Atomic long)
(make-atomic 0UL) ; an (Atomic ulong)
(make-atomic (list 1 2)) ; an (Atomic (List int))
The cell’s type is inferred from value. Untyped integer literals
default to int. Use 0L or 0UL for 64-bit counters to
prevent wrapping.
atomic-ref
function ↑ Functions
(: atomic-ref (-> (Atomic %a) %a))
Returns the current value in the atomic cell.
a- The atomic cell.
- returns
- The currently stored value.
atomic-set!
function ↑ Functions
(: atomic-set! (-> (Atomic %a) %a void))
Stores a value in the atomic cell with a full memory barrier.
a- The atomic cell to update.
value- The new value to store.
Emits a full memory barrier. Preceding and subsequent memory operations on the executing thread cannot be reordered across this store.
atomic-swap!
function ↑ Functions
(: atomic-swap! (-> (Atomic %a) %a %a))
Replaces the value in the atomic cell, returning the previous value.
a- The atomic cell to update.
value- The new value to store.
- returns
- The value held immediately before the swap.
atomic-compare-and-swap!
function ↑ Functions
(: atomic-compare-and-swap! (-> (Atomic %a) %a %a %a))
Stores desired if current value equals expected, returning previous value.
a- The atomic cell.
expected- Value expected to be currently in the cell.
desired- New value to store if comparison succeeds.
- returns
- The value held before the operation. The store succeeded if and only if this equals expected.
(def a (make-atomic 5))
(atomic-compare-and-swap! a 5 6) ; 5 (succeeded; a now holds 6)
(atomic-compare-and-swap! a 5 7) ; 6 (failed; a unchanged at 6)
Reference types compare by reference identity (eq?). Value types
compare by value.
atomic-update!
function ↑ Functions
(: atomic-update! (-> (Atomic %a) (-> %a %a) %a))
Applies a pure function to the value using a compare-and-swap retry loop.
a- The atomic cell to update.
f- Pure transformation function mapping old value to new value.
- returns
- The updated value stored in the cell.
(def seen (make-atomic (list)))
(atomic-update! seen (fun (xs) (Cons 3 xs))) ; (3)
Retries in a loop if concurrent threads modify the value between read and store. Under contention, f may execute multiple times. Function f must be free of side effects (no I/O, mutation, or logging).
atomic-increment!
function ↑ Functions
(: atomic-increment! (-> (Atomic %a) %a))
Increments the integer in the atomic cell by 1, returning the new value.
a- The atomic cell.
- returns
- The updated value after incrementing.
atomic-decrement!
function ↑ Functions
(: atomic-decrement! (-> (Atomic %a) %a))
Decrements the integer in the atomic cell by 1, returning the new value.
a- The atomic cell.
- returns
- The updated value after decrementing.
atomic-add!
function ↑ Functions
(: atomic-add! (-> (Atomic %a) %a %a))
Adds n to the integer in the atomic cell, returning the new value.
a- The atomic cell.
n- The value to add.
- returns
- The updated value after adding n.
atomic-sub!
function ↑ Functions
(: atomic-sub! (-> (Atomic %a) %a %a))
Subtracts n from the integer in the atomic cell, returning the new value.
a- The atomic cell.
n- The value to subtract.
- returns
- The updated value after subtracting n.