Ruby: include/ruby/atomic.h File Reference

Ruby 3.3.7p123 (2025-01-15 revision be31f993d7fa0219d85f7b3c694d454da4ecc10b)

Macros | Typedefs
atomic.h File Reference

Atomic operations. More...

`#include "ruby/internal/config.h"`
`#include "ruby/assert.h"`
`#include "ruby/backward/2/limits.h"`
`#include "ruby/internal/attr/artificial.h"`
`#include "ruby/internal/attr/noalias.h"`
`#include "ruby/internal/attr/nonnull.h"`
`#include "ruby/internal/compiler_since.h"`
`#include "ruby/internal/cast.h"`
`#include "ruby/internal/value.h"`
`#include "ruby/internal/static_assert.h"`
`#include "ruby/internal/stdbool.h"`

Go to the source code of this file.

## Macros
#define | RUBY_ATOMIC_GENERIC_MACRO 1
#define | RUBY_ATOMIC_FETCH_ADD(var, val)
| Atomically replaces the value pointed by `var` with the result of addition of `val` to the old value of `var`.
#define | RUBY_ATOMIC_FETCH_SUB(var, val)
| Atomically replaces the value pointed by `var` with the result of subtraction of `val` to the old value of `var`.
#define | RUBY_ATOMIC_OR(var, val)
| Atomically replaces the value pointed by `var` with the result of bitwise OR between `val` and the old value of `var`.
#define | RUBY_ATOMIC_EXCHANGE(var, val)
| Atomically replaces the value pointed by `var` with `val`.
#define | RUBY_ATOMIC_CAS(var, oldval, newval)
| Atomic compare-and-swap.
#define | RUBY_ATOMIC_LOAD(var)
| Atomic load.
#define | RUBY_ATOMIC_SET(var, val)
| Identical to RUBY_ATOMIC_EXCHANGE, except for the return type.
#define | RUBY_ATOMIC_ADD(var, val)
| Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type.
#define | RUBY_ATOMIC_SUB(var, val)
| Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type.
#define | RUBY_ATOMIC_INC(var)
| Atomically increments the value pointed by `var`.
#define | RUBY_ATOMIC_DEC(var)
| Atomically decrements the value pointed by `var`.
#define | RUBY_ATOMIC_SIZE_INC(var)
| Identical to RUBY_ATOMIC_INC, except it expects its argument is `size_t`.
#define | RUBY_ATOMIC_SIZE_DEC(var)
| Identical to RUBY_ATOMIC_DEC, except it expects its argument is `size_t`.
#define | RUBY_ATOMIC_SIZE_EXCHANGE(var, val)
| Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are `size_t`.
#define | RUBY_ATOMIC_SIZE_CAS(var, oldval, newval)
| Identical to RUBY_ATOMIC_CAS, except it expects its arguments are `size_t`.
#define | RUBY_ATOMIC_SIZE_ADD(var, val)
| Identical to RUBY_ATOMIC_ADD, except it expects its arguments are `size_t`.
#define | RUBY_ATOMIC_SIZE_SUB(var, val)
| Identical to RUBY_ATOMIC_SUB, except it expects its arguments are `size_t`.
#define | RUBY_ATOMIC_PTR_EXCHANGE(var, val)
| Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are `void*`.
#define | RUBY_ATOMIC_PTR_LOAD(var)
| Identical to RUBY_ATOMIC_LOAD, except it expects its arguments are `void*`.
#define | RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
| Identical to RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.
#define | RUBY_ATOMIC_VALUE_EXCHANGE(var, val)
| Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are VALUE.
#define | RUBY_ATOMIC_VALUE_CAS(var, oldval, newval)
| Identical to RUBY_ATOMIC_CAS, except it expects its arguments are VALUE.

## Typedefs
using | rb_atomic_t = std::atomic<unsigned>
| Type that is eligible for atomic operations.

## Detailed Description

Atomic operations.

Author
  Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org

Copyright
  This file is a part of the programming language Ruby. Permission is hereby granted, to either redistribute and/or modify this file, provided that the conditions mentioned in the file COPYING are met. Consult the file for details.

Warning
  Symbols prefixed with either `RBIMPL` or `rbimpl` are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will.

Note
  To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance `__VA_ARGS__` is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98.

Basically, if we could assume either C11 or C++11, these macros are just redundant. Sadly we cannot. We have to do them ourselves.

Definition in file atomic.h.

## Macro Definition Documentation

## ◆ RUBY_ATOMIC_ADD

#define RUBY_ATOMIC_ADD | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_add(&(var), (val))

Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to add.

Returns
  void

Postcondition
  `var` holds `var + val`.

Definition at line 168 of file atomic.h.

## ◆ RUBY_ATOMIC_CAS

#define RUBY_ATOMIC_CAS | ( |  | var,
|  |  | oldval,
|  |  | newval )

Value:
rbimpl_atomic_cas(&(var), (oldval), (newval))

Atomic compare-and-swap.

This stores `val` to `var` if and only if the assignment changes the value of `var` from `oldval` to `newval`. You can detect whether the assignment happened or not using the return value.

Parameters

  var | A variable of rb_atomic_t.
  oldval | Expected value of `var` before the assignment.
  newval | What you want to store at `var`.

Return values

  oldval | Successful assignment (`var` is now `newval`).
  otherwise | Something else is at `var`; not updated.

Definition at line 138 of file atomic.h.

## ◆ RUBY_ATOMIC_DEC

#define RUBY_ATOMIC_DEC | ( |  | var | ) |

Value:
rbimpl_atomic_dec(&(var))

Atomically decrements the value pointed by `var`.

Parameters

  var | A variable of rb_atomic_t.

Returns
  void

Postcondition
  `var` holds `var - 1`.

Definition at line 196 of file atomic.h.

## ◆ RUBY_ATOMIC_EXCHANGE

#define RUBY_ATOMIC_EXCHANGE | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_exchange(&(var), (val))

Atomically replaces the value pointed by `var` with `val`.

This is just an assignment, but you can additionally know the previous value.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to set.

Returns
  What was stored in `var` before the assignment.

Postcondition
  `var` holds `val`.

Definition at line 125 of file atomic.h.

## ◆ RUBY_ATOMIC_FETCH_ADD

#define RUBY_ATOMIC_FETCH_ADD | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_fetch_add(&(var), (val))

Atomically replaces the value pointed by `var` with the result of addition of `val` to the old value of `var`.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to add.

Returns
  What was stored in `var` before the addition.

Postcondition
  `var` holds `var + val`.

Definition at line 91 of file atomic.h.

## ◆ RUBY_ATOMIC_FETCH_SUB

#define RUBY_ATOMIC_FETCH_SUB | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_fetch_sub(&(var), (val))

Atomically replaces the value pointed by `var` with the result of subtraction of `val` to the old value of `var`.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to subtract.

Returns
  What was stored in `var` before the subtraction.

Postcondition
  `var` holds `var - val`.

Definition at line 102 of file atomic.h.

## ◆ RUBY_ATOMIC_GENERIC_MACRO

#define RUBY_ATOMIC_GENERIC_MACRO 1

Definition at line 60 of file atomic.h.

## ◆ RUBY_ATOMIC_INC

#define RUBY_ATOMIC_INC | ( |  | var | ) |

Value:
rbimpl_atomic_inc(&(var))

Atomically increments the value pointed by `var`.

Parameters

  var | A variable of rb_atomic_t.

Returns
  void

Postcondition
  `var` holds `var + 1`.

Definition at line 187 of file atomic.h.

## ◆ RUBY_ATOMIC_LOAD

#define RUBY_ATOMIC_LOAD | ( |  | var | ) |

Value:
rbimpl_atomic_load(&(var))

Atomic load.

This loads `var` with an atomic intrinsic and returns its value.

Parameters

  var | A variable of rb_atomic_t

Returns
  What was stored in `var`j

Definition at line 148 of file atomic.h.

## ◆ RUBY_ATOMIC_OR

#define RUBY_ATOMIC_OR | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_or(&(var), (val))

Atomically replaces the value pointed by `var` with the result of bitwise OR between `val` and the old value of `var`.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to mix.

Returns
  void

Postcondition
  `var` holds `var | val`.

Note
  For portability, this macro can return void.

Definition at line 114 of file atomic.h.

Referenced by rb_postponed_job_trigger().

## ◆ RUBY_ATOMIC_PTR_CAS

#define RUBY_ATOMIC_PTR_CAS | ( |  | var,
|  |  | oldval,
|  |  | newval )

Value:
RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (oldval), (newval)))

Identical to RUBY_ATOMIC_CAS, except it expects its arguments are `void*`.

There are cases where rb_atomic_t is 32bit while `void*` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `void*`.
  oldval | Expected value of `var` before the assignment.
  newval | What you want to store at `var`.

Return values

  oldval | Successful assignment (`var` is now `newval`).
  otherwise | Something else is at `var`; not updated.

Definition at line 313 of file atomic.h.

Referenced by rb_postponed_job_preregister().

## ◆ RUBY_ATOMIC_PTR_EXCHANGE

#define RUBY_ATOMIC_PTR_EXCHANGE | ( |  | var,
|  |  | val )

Value:
RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))

Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are `void*`.

There are cases where rb_atomic_t is 32bit while `void*` is 64bit. This should be used for pointer related operations to support such platforms.

Parameters

  var | A variable of `void *`.
  val | Value to set.

Returns
  What was stored in `var` before the assignment.

Postcondition
  `var` holds `val`.

Definition at line 288 of file atomic.h.

Referenced by rb_postponed_job_preregister().

## ◆ RUBY_ATOMIC_PTR_LOAD

#define RUBY_ATOMIC_PTR_LOAD | ( |  | var | ) |

Value:
RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))

Identical to RUBY_ATOMIC_LOAD, except it expects its arguments are `void*`.

There are cases where rb_atomic_t is 32bit while `void*` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `void*`

Returns
  The value of `var` (without tearing)

Definition at line 299 of file atomic.h.

## ◆ RUBY_ATOMIC_SET

#define RUBY_ATOMIC_SET | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_set(&(var), (val))

Identical to RUBY_ATOMIC_EXCHANGE, except for the return type.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to set.

Returns
  void

Postcondition
  `var` holds `val`.

Definition at line 158 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_ADD

#define RUBY_ATOMIC_SIZE_ADD | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_size_add(&(var), (val))

Identical to RUBY_ATOMIC_ADD, except it expects its arguments are `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.
  val | Value to add.

Returns
  void

Postcondition
  `var` holds `var + val`.

Definition at line 258 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_CAS

#define RUBY_ATOMIC_SIZE_CAS | ( |  | var,
|  |  | oldval,
|  |  | newval )

Value:
rbimpl_atomic_size_cas(&(var), (oldval), (newval))

Identical to RUBY_ATOMIC_CAS, except it expects its arguments are `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.
  oldval | Expected value of `var` before the assignment.
  newval | What you want to store at `var`.

Return values

  oldval | Successful assignment (`var` is now `newval`).
  otherwise | Something else is at `var`; not updated.

Definition at line 245 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_DEC

#define RUBY_ATOMIC_SIZE_DEC | ( |  | var | ) |

Value:
rbimpl_atomic_size_dec(&(var))

Identical to RUBY_ATOMIC_DEC, except it expects its argument is `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.

Returns
  void

Postcondition
  `var` holds `var - 1`.

Definition at line 218 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_EXCHANGE

#define RUBY_ATOMIC_SIZE_EXCHANGE | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_size_exchange(&(var), (val))

Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.
  val | Value to set.

Returns
  What was stored in `var` before the assignment.

Postcondition
  `var` holds `val`.

Definition at line 231 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_INC

#define RUBY_ATOMIC_SIZE_INC | ( |  | var | ) |

Value:
rbimpl_atomic_size_inc(&(var))

Identical to RUBY_ATOMIC_INC, except it expects its argument is `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.

Returns
  void

Postcondition
  `var` holds `var + 1`.

Definition at line 207 of file atomic.h.

## ◆ RUBY_ATOMIC_SIZE_SUB

#define RUBY_ATOMIC_SIZE_SUB | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_size_sub(&(var), (val))

Identical to RUBY_ATOMIC_SUB, except it expects its arguments are `size_t`.

There are cases where rb_atomic_t is 32bit while `size_t` is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `size_t`.
  val | Value to subtract.

Returns
  void

Postcondition
  `var` holds `var - val`.

Definition at line 270 of file atomic.h.

## ◆ RUBY_ATOMIC_SUB

#define RUBY_ATOMIC_SUB | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_sub(&(var), (val))

Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type.

Parameters

  var | A variable of rb_atomic_t.
  val | Value to subtract.

Returns
  void

Postcondition
  `var` holds `var - val`.

Definition at line 178 of file atomic.h.

## ◆ RUBY_ATOMIC_VALUE_CAS

#define RUBY_ATOMIC_VALUE_CAS | ( |  | var,
|  |  | oldval,
|  |  | newval )

Value:
rbimpl_atomic_value_cas(&(var), (oldval), (newval))

Identical to RUBY_ATOMIC_CAS, except it expects its arguments are VALUE.

There are cases where rb_atomic_t is 32bit while VALUE is 64bit. This should be used for size related operations to support such platforms.

Parameters

  var | A variable of `void*`.
  oldval | Expected value of `var` before the assignment.
  newval | What you want to store at `var`.

Return values

  oldval | Successful assignment (`var` is now `newval`).
  otherwise | Something else is at `var`; not updated.

Definition at line 341 of file atomic.h.

## ◆ RUBY_ATOMIC_VALUE_EXCHANGE

#define RUBY_ATOMIC_VALUE_EXCHANGE | ( |  | var,
|  |  | val )

Value:
rbimpl_atomic_value_exchange(&(var), (val))

Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are VALUE.

There are cases where rb_atomic_t is 32bit while VALUE is 64bit. This should be used for pointer related operations to support such platforms.

Parameters

  var | A variable of VALUE.
  val | Value to set.

Returns
  What was stored in `var` before the assignment.

Postcondition
  `var` holds `val`.

Definition at line 327 of file atomic.h.

## Typedef Documentation

## ◆ rb_atomic_t

using rb_atomic_t = std::atomic<unsigned>

Type that is eligible for atomic operations.

Depending on your host platform you might have more than one such type, but we choose one of them anyways.

Definition at line 69 of file atomic.h.