NAME
ainc, adec, cas, casv, casp, loadlink, storecond, _tas – atomic read–modify–write operations

SYNOPSIS
#include <u.h>
#include <libc.h>

long ainc(long *addr);

long adec(long *addr);

int cas(int *addr, int ov, int nv);

int casv(u64int *addr, u64int ov, u64int nv);

int casp(void **addr, void *ov, void *nv);

int _tas(ulong *addr);

ulong loadlink(ulong*);

int storecond(ulong*, ulong);

DESCRIPTION
These functions provide access to atomic operations, useful for synchronization. When viewed from other processes including those on other cores, the implementation guarantees that memory accesses by the process before an atomic operation are completed and visible before that operation, and the operation is completed and its result is visible before any further memory accesses, even on hardware that can otherwise reorder memory accesses (e.g., non–Intel architectures).

Ainc atomically increments the value pointed to by addr and returns the new value. Adec is similar but decrements.

Cas, casv and casp implement Compare–and–Swap, on, respectively, int, vlong and void* values. They return boolean success instead of the old value, unlike generic Compare–and–Swap, which atomically sets *addr to nv only if it contains ov, and returns the old value. The availability of these functions depends on the CPU architecture: Pentium III and later, as well as AMD64 have 64–bit CAS instructions; other architectures don't. ARM v5 architecture processors and earlier do not have CAS (nor have they Load–Linked or Store–Conditional). These instructions are, however, emulated by the Plan 9 kernel. All other architectures have 32–bit CAS.

_tas implements Test–and–Set (atomically set *addr non–zero and return previous contents), which is available on all architectures and used for the implementation of kernel locks (see lock(2) and thread(2)).

Loadlink and storecond access the load–linked and store–conditional instructions present on MIPS (LL/SC), ARM (Strex/Ldrex), PowerPC (LWAR/STWCCC), and RISC–V (LR/SC). These are not present on Pentium or AMD64. On the architectures that have load–linked and store–conditional, these may be used to implement compare–and–swap.

SOURCE
/sys/src/libc/*/atom.s
/sys/src/libc/*/tas.s

SEE ALSO
lock(2), semacquire(2), thread(2)

DIAGNOSTICS
The cas* functions and storecond return 0 for failure and 1 for success.
Copyright © 2025 Plan 9 Foundation