6.22.4 Atomics

When accessing data in parallel from multiple threads, updates made by one thread are not generally guaranteed to be visible by another thread. It could be that your hardware requires special instructions to be emitted to propagate a change from one CPU core to another. Or, it could be that your hardware updates values with a sequence of instructions, and a parallel thread could see a value that is in the process of being updated but not fully updated.

Atomic references solve this problem. Atomics are a standard, primitive facility to allow for concurrent access and update of mutable variables from multiple threads with guaranteed forward-progress and well-defined intermediate states.

Atomic references serve not only as a hardware memory barrier but also as a compiler barrier. Normally a compiler might choose to reorder or elide certain memory accesses due to optimizations like common subexpression elimination. Atomic accesses however will not be reordered relative to each other, and normal memory accesses will not be reordered across atomic accesses.

As an implementation detail, currently all atomic accesses and updates use the sequential consistency memory model from C11. We may relax this in the future to the acquire/release semantics, which still issues a memory barrier so that non-atomic updates are not reordered across atomic accesses or updates.

To use Guile’s atomic operations, load the (ice-9 atomic) module:

(use-modules (ice-9 atomic))
Scheme Procedure: make-atomic-box init

Return an atomic box initialized to value init.

Scheme Procedure: atomic-box? obj

Return #t if obj is an atomic-box object, else return #f.

Scheme Procedure: atomic-box-ref box

Fetch the value stored in the atomic box box and return it.

Scheme Procedure: atomic-box-set! box val

Store val into the atomic box box.

Scheme Procedure: atomic-box-swap! box val

Store val into the atomic box box, and return the value that was previously stored in the box.

Scheme Procedure: atomic-box-compare-and-swap! box expected desired

If the value of the atomic box box is the same as, expected (in the sense of eq?), replace the contents of the box with desired. Otherwise does not update the box. Returns the previous value of the box in either case, so you can know if the swap worked by checking if the return value is eq? to expected.