True when T is a 1, 2, 4 or 8 byte integer, bool, float, pointer, enum or procedure, the types the atomic procedures accept.
#import "Atomics";
Lock-free reads and updates of a shared integer, pointer or bool.
- atomic_add, atomic_increment and atomic_decrement for counters.
- atomic_and, atomic_or, atomic_xor and atomic_bit_test_and_set for flag words.
- atomic_read, atomic_write and atomic_swap for plain loads, stores and exchanges.
Targets must be 1, 2, 4 or 8 bytes and naturally aligned. compare_and_swap is built into the language.
counter: s64;
before := atomic_add(*counter, 5);
assert(before == 0 && counter == 5);Procedures#
(T: Type) -> bool
(dest: *$T, to_add: $I) -> T
Adds to_add to *dest and returns the value *dest held before.
hits: s32 = 10;
before := atomic_add(*hits, 3);
assert(before == 10 && hits == 13);↗(dest: *$T)
Adds one to *dest.
n: u8;
atomic_increment(*n);
assert(n == 1);↗(dest: *$T) -> bool
Subtracts one from *dest. Returns true when the result is zero, which makes it fit for reference counts.
refs: s64 = 2;
assert(!atomic_decrement(*refs));
assert(atomic_decrement(*refs));↗(dest: *$T, value: T)
Sets *dest to *dest & value.
flags: u32 = 0b1100;
atomic_and(*flags, 0b1010);
assert(flags == 0b1000);↗(dest: *$T, value: T)
Sets *dest to *dest | value.
(dest: *$T, value: $I)
Sets *dest to *dest ^ value.
flags: u32 = 0b0110;
atomic_xor(*flags, 0b0011);
assert(flags == 0b0101);↗(dest: *$T, i: s64) -> bool
Sets bit i of *dest and returns whether it was already set. A negative i counts from the top bit. The target must be 2, 4 or 8 bytes.
word: u32;
assert(!atomic_bit_test_and_set(*word, 3));
assert(atomic_bit_test_and_set(*word, 3));
assert(word == 0b1000);↗Constants#
:: atomic_exchange
Stores value in dest and returns what was there before.
x := 1;
old := atomic_swap(*x, 2);
assert(old == 1 && x == 2);↗:: atomic_load
Returns the value at pointer.
x := 7;
assert(atomic_read(*x) == 7);↗:: atomic_store
Stores value at pointer.
x := 0;
atomic_write(*x, 9);
assert(x == 9);↗