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. |