---
name: "libatomic-ops"
section: "3"
platform: "linux"
package: "libatomic-ops-dev"
version: "7.8.2-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/libatomic-ops"
---

# libatomic-ops(3)

Library providing user level atomic operations

## NAME

libatomic-ops - Library providing user level atomic operations

## SYNOPSIS

**#include \<atomic\_ops.h\>**

**cc ... -latomic\_ops**

Note that all operations have an additional barrier option that can be set explicitly.

**void AO\_load(AO\_t \*addr)**\
 **void AO\_store(AO\_t \*addr, AO\_t val)**

**int AO\_test\_and\_set (AO\_t \*addr)**

**AO\_t AO\_fetch\_and\_add(AO\_t \*addr, AO\_t incr)**\
 **AO\_t AO\_fetch\_and\_add1(AO\_t \*addr)**\
 **AO\_t AO\_fetch\_and\_sub1(AO\_t \*addr)**

**void AO\_or(AO\_t \*p, AO\_t incr)**\
 **int AO\_compare\_and\_swap(AO\_t \*addr, AO\_t old, AO\_t new\_val)**

## DESCRIPTION

**libatomic-ops** offers a programming interface to a comprehensive range of atomic operations at user level.

We define various atomic operations on memory in a machine-specific way.  Unfortunately, this is complicated by the fact that these may or may not be combined with various memory barriers.  Thus the actual operations we define have the form  **AO\_\<atomic-op\>\_\<barrier\>** for all plausible combinations of \<atomic-op\> and \<barrier\>.

The valid barrier suffixes are

- **\_release**

  Earlier operations may not be delayed past it.

- **\_acquire**

  Later operations may not move ahead of it.

- **\_read**

  Subsequent reads must follow this operation and preceding reads.

- **\_write**

  Earlier writes precede both this operation and later writes.

- **\_full**

  Ordered with respect to both earlier and later memops.

- **\_release\_write**

  Ordered with respect to earlier writes.

- **\_acquire\_read**

  Ordered with repsect to later reads.

This of course results in a mild combinatorial explosion.

The library will find the least expensive way to implement your operations on the  applicable hardware.  In many cases that will involve, for example,  a stronger memory barrier, or a combination of hardware primitives.

Note that atomicity guarantees are valid only if both readers and  writers use AO\_ operations to access the shared value, while ordering  constraints are intended to apply all memory operations.   If a location can potentially be accessed simultaneously from  multiple threads, and one of those accesses may be a write access,  then all such accesses to that location should be  through AO\_ primitives. However if AO\_ operations enforce sufficient  ordering to ensure that a location x cannot be accessed concurrently, or can only  be read concurrently, then x can be accessed via ordinary references and assignments.

All operations operate on an **AO\_t** value, which is the natural word size for the architecture.

**AO\_load** and **AO\_store** load and store the specified pointer address.

**AO\_test\_and\_set** atomically replaces an address with **AO\_TS\_SET** and returns the prior value.  An **AO\_TS\_t location can be reset with the** **AO\_CLEAR** macro, which usually uses **AO\_store\_release**

**AO\_fetch\_and\_add** takes an address and a value to add.

**AO\_fetch\_and\_add1** and **AO\_fetch\_and\_sub1** are provided since they may have faster implemenations on some hardware

**AO\_or** atomically ors an  *AO\_t* value into a memory location, but does not provide  access to the original

**AO\_compare\_and\_swap** takes an address, an old value and a new value and returns an int. *non-zero* indicates the compare and swap succeeded.

## SEE ALSO

[libatomic-stack(3)](/libatomic-stack/3.md), [libatomic-malloc(3)](/libatomic-malloc/3.md)

## AUTHOR

This manual page was written by Ian Wienand \<ianw@gelato.unsw.edu.au\>, based on comments in the source code.  It was written for the Debian project (but may be used by others).
