Atomic Operations (v0.2.2)

Atomic read-modify-write and compare-and-swap builtins (unstable).

Latest

Overview

The atomic builtins perform read-modify-write and compare-and-swap operations on a memory location. They map to the LLVM atomicrmw and cmpxchg instructions.

This feature is unstable. It only works when the compiler runs in unstable mode, and it can change or disappear.

Primary source: syntax/atomics/atomics.md

Syntax Signatures

fn example() void @public {
    var atomicRelax counter: u32 = 10;
    var old: u32 = atomicAdd(counter, 5);
}

Behavior and Use

The destination of an atomic operation must be a variable declared with an atomic ordering modificator, such as atomicRelax or atomicSync.

The operation inherits the ordering from the destination declaration. atomicNone and atomicFree do not describe an atomic operation and are rejected.

Compare-and-swap follows the C11 model: expected is passed by address and is updated with the current value on failure. The builtin returns true when the swap happened.

Read-Modify-Write Builtins

Each builtin writes a value atomically and returns the previous value. The destination and value must be integers.

Compare-And-Swap

atomicCompareAndSwap compares the destination against an expected value and swaps in a new value when they match.

Example

fn main() s32 @public {
    var atomicRelax counter: u32 = 20;
    var expected: u32 = 20;
    var swapped: bool = atomicCompareAndSwap(counter, expected, 30, atomicSync, atomicRelax);

    if swapped && counter == 30 {
        return 0;
    }

    return 1;
}
// Requires -mode unstable.
fn main() s32 @public {
    var atomicRelax nextTicket: u32 = 100;
    var ticket: u32 = atomicAdd(nextTicket, 1);

    if ticket == 100 && nextTicket == 101 {
        return 0;
    }

    return 1;
}

Back to language reference