Atomic intrinsics v0.1.0

Source
The atomic loads, stores, exchanges and read-modify-write operations, memory orders and fences that the Atomic package builds on.

MemoryOrder

pub enum MemoryOrder: uint8 {
    Relaxed = 0,
    Acquire = 1,
    Release = 2,
    AcquireRelease = 3,
    SequentiallyConsistent = 4
}

Which other memory operations may be reordered across an atomic one. The weakest ordering that makes a program correct is also the fastest, and a stronger one is never wrong. When in doubt, SequentiallyConsistent gives every thread one agreed order of all such operations.

Source

Cases

NameValueDescription
Relaxed0No ordering: the operation itself is atomic, and nothing around it is held back. Right for counters whose value no other memory depends on.
Acquire1Later operations of this thread are not moved before this load, so whatever a releasing thread wrote before its release is visible after this acquire. For loads and the read half of read-modify-write operations.
Release2Earlier operations of this thread are not moved after this store, so they are visible to a thread that acquires what it stores. For stores and the write half of read-modify-write operations.
AcquireRelease3Both Acquire and Release, for a read-modify-write operation that does both.
SequentiallyConsistent4AcquireRelease, and also a single order of every sequentially consistent operation that all threads agree on.

AtomicLoad<T>

pub func AtomicLoad<T>(address: *T, order: MemoryOrder) -> T

Reads the value at address atomically. order must be Relaxed, Acquire or SequentiallyConsistent, written at the call. address must be aligned to the size of T and point at memory every thread that touches it reaches only through atomic operations. Runs in constant time and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, bool, or a pointer

Parameters

NameTypeDescription
address*Tthe value to read
orderMemoryOrderwhich other operations may move across this one

Returns: the value read

AtomicStore<T>

pub func AtomicStore<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
)

Writes value to address atomically. order must be Relaxed, Release or SequentiallyConsistent, written at the call. address must be aligned to the size of T. Runs in constant time and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, bool, or a pointer

Parameters

NameTypeDescription
address*var Twhere to write
valueTwhat to write
orderMemoryOrderwhich other operations may move across this one

AtomicExchange<T>

pub func AtomicExchange<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Writes value to address and returns what was there, as one atomic step. Any ordering is allowed. address must be aligned to the size of T. Runs in constant time and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, bool, or a pointer

Parameters

NameTypeDescription
address*var Twhere to write
valueTwhat to write
orderMemoryOrderwhich other operations may move across this one

Returns: the value that was replaced

AtomicCompareExchange<T>

pub func AtomicCompareExchange<T>(
    address: *var T,
    expected: T,
    desired: T,
    success: MemoryOrder,
    failure: MemoryOrder
) -> T

Writes desired to address if it holds expected, and returns what it held, as one atomic step. The write happened exactly when the returned value equals expected. success orders the operation when it writes, and failure when it only reads; failure may not be Release or AcquireRelease, nor acquire more than success does. address must be aligned to the size of T. Never fails spuriously. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, bool, or a pointer

Parameters

NameTypeDescription
address*var Tthe value to compare and replace
expectedTthe value address must hold for the write to happen
desiredTthe value to write
successMemoryOrderthe ordering when the write happens
failureMemoryOrderthe ordering when it does not

Returns: the value address held before the operation

AtomicFetchAdd<T>

pub func AtomicFetchAdd<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Adds value to the integer at address and returns what was there, as one atomic step. The sum wraps on overflow, as two's complement arithmetic does. Any ordering is allowed. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits

Parameters

NameTypeDescription
address*var Tthe integer to add to
valueTwhat to add
orderMemoryOrderwhich other operations may move across this one

Returns: the value before the addition

AtomicFetchSub<T>

pub func AtomicFetchSub<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Subtracts value from the integer at address and returns what was there, as one atomic step. The difference wraps on overflow. Any ordering is allowed. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits

Parameters

NameTypeDescription
address*var Tthe integer to subtract from
valueTwhat to subtract
orderMemoryOrderwhich other operations may move across this one

Returns: the value before the subtraction

AtomicFetchAnd<T>

pub func AtomicFetchAnd<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Combines the value at address with value by bitwise and, and returns what was there, as one atomic step. Any ordering is allowed. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, or bool

Parameters

NameTypeDescription
address*var Tthe value to combine
valueTthe bits to keep
orderMemoryOrderwhich other operations may move across this one

Returns: the value before the operation

AtomicFetchOr<T>

pub func AtomicFetchOr<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Combines the value at address with value by bitwise or, and returns what was there, as one atomic step. Any ordering is allowed. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, or bool

Parameters

NameTypeDescription
address*var Tthe value to combine
valueTthe bits to set
orderMemoryOrderwhich other operations may move across this one

Returns: the value before the operation

AtomicFetchXor<T>

pub func AtomicFetchXor<T>(
    address: *var T,
    value: T,
    order: MemoryOrder
) -> T

Combines the value at address with value by bitwise exclusive or, and returns what was there, as one atomic step. Any ordering is allowed. Runs in constant time apart from contention and allocates nothing.

Source

Type parameters

NameDescription
Tan integer of 8 to 64 bits, or bool

Parameters

NameTypeDescription
address*var Tthe value to combine
valueTthe bits to flip
orderMemoryOrderwhich other operations may move across this one

Returns: the value before the operation

Fence

pub func Fence(order: MemoryOrder)

Orders this thread's memory operations without touching memory. order must not be Relaxed, which would order nothing. An Acquire fence keeps later operations after earlier loads, a Release fence keeps earlier operations before later stores, and SequentiallyConsistent does both and takes part in the single order of sequentially consistent operations. Runs in constant time and allocates nothing.

Source

Parameters

NameTypeDescription
orderMemoryOrderwhat the fence holds back

SpinHint

pub func SpinHint()

Tells the processor that the thread is waiting in a loop for another thread. It saves power and lets a sibling hardware thread run, and has no effect on memory. A loop that waits long should sleep instead. Runs in constant time and allocates nothing.

Source