ATOM(2) ATOM(2) NAME ainc, adec, cas, cas32, cas64, casp, casl, loadlink, storecond, _tas - atomic RMW operations SYNOPSIS #include <u.h> #include <libc.h> long ainc(long *addr); long adec(long *addr); int cas32(u32int *addr, u32int ov, u32int nv); int cas64(u64int *addr, u64int ov, u64int nv); int cas(int *addr, int ov, int nv); int casp(void **addr, void *ov, void *nv); int casl(ulong *addr, ulong ov, ulong nv); int _tas(ulong *addr); ulong loadlink(ulong*); int storecond(ulong*, ulong); DESCRIPTION Ainc atomically increments the value pointed to by addr and returns the new value. Adec atomically decrements the value pointed to by addr and returns the new value. Cas, cas32, cas64, casp, and casl implement Compare-and-Swap on, respectively, int, u32int, u64int, void*, and ulong val- ues. 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-5 processors and earlier do not have CAS (nor have they Load- Linked or Store-Conditional ). These instructions are, how- ever, emulated by the Plan 9 kernel. All other architec- tures have 32-bit CAS. _tas implements Test-and-Set, 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- Page 1 Plan 9 (printed 12/22/24) ATOM(2) ATOM(2) conditional instructions present on MIPS (LL/SC), ARM (Strex/Ldrex), PowerPC (LWAR/STWCCC), Alpha (MOVLL, MOVLC). These are not present on Pentium or AMD64. On the architectures that have load-linked and store- conditional, these are used to implement compare-and-swap. SOURCE /sys/src/libc/*/atom.s /sys/src/libc/*/tas.s SEE ALSO semacquire(2), lock(2), thread(2) DIAGNOSTICS The CAS functions, _tas, and storecond return 0 for failure and 1 for success. Page 2 Plan 9 (printed 12/22/24)