Ruby 3.5.0dev (2025-07-23 revision 33363030e1846c9f2cdbdcc9b77c11efbda3d522)
Macros | Typedefs
atomic.h File Reference

(33363030e1846c9f2cdbdcc9b77c11efbda3d522)

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"
Include dependency graph for atomic.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define RUBY_ATOMIC_GENERIC_MACRO   1
 
#define RUBY_ATOMIC_FETCH_ADD(var, val)   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.
 
#define RUBY_ATOMIC_FETCH_SUB(var, val)   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.
 
#define RUBY_ATOMIC_OR(var, val)   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.
 
#define RUBY_ATOMIC_EXCHANGE(var, val)   rbimpl_atomic_exchange(&(var), (val))
 Atomically replaces the value pointed by var with val.
 
#define RUBY_ATOMIC_CAS(var, oldval, newval)    rbimpl_atomic_cas(&(var), (oldval), (newval))
 Atomic compare-and-swap.
 
#define RUBY_ATOMIC_LOAD(var)   rbimpl_atomic_load(&(var))
 Atomic load.
 
#define RUBY_ATOMIC_SET(var, val)   rbimpl_atomic_set(&(var), (val))
 Identical to RUBY_ATOMIC_EXCHANGE, except for the return type.
 
#define RUBY_ATOMIC_ADD(var, val)   rbimpl_atomic_add(&(var), (val))
 Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type.
 
#define RUBY_ATOMIC_SUB(var, val)   rbimpl_atomic_sub(&(var), (val))
 Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type.
 
#define RUBY_ATOMIC_INC(var)   rbimpl_atomic_inc(&(var))
 Atomically increments the value pointed by var.
 
#define RUBY_ATOMIC_DEC(var)   rbimpl_atomic_dec(&(var))
 Atomically decrements the value pointed by var.
 
#define RUBY_ATOMIC_SIZE_FETCH_ADD(var, val)   rbimpl_atomic_size_fetch_add(&(var), (val))
 Identical to RUBY_ATOMIC_FETCH_ADD, except it expects its arguments to be size_t.
 
#define RUBY_ATOMIC_SIZE_INC(var)   rbimpl_atomic_size_inc(&(var))
 Identical to RUBY_ATOMIC_INC, except it expects its argument is size_t.
 
#define RUBY_ATOMIC_SIZE_DEC(var)   rbimpl_atomic_size_dec(&(var))
 Identical to RUBY_ATOMIC_DEC, except it expects its argument is size_t.
 
#define RUBY_ATOMIC_SIZE_EXCHANGE(var, val)    rbimpl_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)    rbimpl_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)   rbimpl_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)   rbimpl_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)    RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))
 Identical to RUBY_ATOMIC_EXCHANGE, except it expects its arguments are void*.
 
#define RUBY_ATOMIC_PTR_LOAD(var)    RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))
 Identical to RUBY_ATOMIC_LOAD, except it expects its arguments are void*.
 
#define RUBY_ATOMIC_PTR_SET(var, val)    rbimpl_atomic_ptr_set((volatile void **)&(var), (val))
 Identical to RUBY_ATOMIC_SET, except it expects its arguments are void*.
 
#define RUBY_ATOMIC_PTR_CAS(var, oldval, newval)    RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (void *)(oldval), (void *)(newval)))
 Identical to RUBY_ATOMIC_CAS, except it expects its arguments are void*.
 
#define RUBY_ATOMIC_VALUE_SET(var, val)    rbimpl_atomic_value_set(&(var), (val))
 Identical to RUBY_ATOMIC_SET, except it expects its arguments are VALUE.
 
#define RUBY_ATOMIC_VALUE_EXCHANGE(var, val)    rbimpl_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)    rbimpl_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
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 
)    rbimpl_atomic_add(&(var), (val))

Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type.

Parameters
varA variable of rb_atomic_t.
valValue to add.
Returns
void
Postcondition
var holds var + val.

Definition at line 173 of file atomic.h.

◆ RUBY_ATOMIC_CAS

#define RUBY_ATOMIC_CAS (   var,
  oldval,
  newval 
)     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
varA variable of rb_atomic_t.
oldvalExpected value of var before the assignment.
newvalWhat you want to store at var.
Return values
oldvalSuccessful assignment (var is now newval).
otherwiseSomething else is at var; not updated.

Definition at line 143 of file atomic.h.

◆ RUBY_ATOMIC_DEC

#define RUBY_ATOMIC_DEC (   var)    rbimpl_atomic_dec(&(var))

Atomically decrements the value pointed by var.

Parameters
varA variable of rb_atomic_t.
Returns
void
Postcondition
var holds var - 1.

Definition at line 201 of file atomic.h.

◆ RUBY_ATOMIC_EXCHANGE

#define RUBY_ATOMIC_EXCHANGE (   var,
  val 
)    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
varA variable of rb_atomic_t.
valValue to set.
Returns
What was stored in var before the assignment.
Postcondition
var holds val.

Definition at line 130 of file atomic.h.

◆ RUBY_ATOMIC_FETCH_ADD

#define RUBY_ATOMIC_FETCH_ADD (   var,
  val 
)    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
varA variable of rb_atomic_t.
valValue to add.
Returns
What was stored in var before the addition.
Postcondition
var holds var + val.

Definition at line 96 of file atomic.h.

◆ RUBY_ATOMIC_FETCH_SUB

#define RUBY_ATOMIC_FETCH_SUB (   var,
  val 
)    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
varA variable of rb_atomic_t.
valValue to subtract.
Returns
What was stored in var before the subtraction.
Postcondition
var holds var - val.

Definition at line 107 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)    rbimpl_atomic_inc(&(var))

Atomically increments the value pointed by var.

Parameters
varA variable of rb_atomic_t.
Returns
void
Postcondition
var holds var + 1.

Definition at line 192 of file atomic.h.

◆ RUBY_ATOMIC_LOAD

#define RUBY_ATOMIC_LOAD (   var)    rbimpl_atomic_load(&(var))

Atomic load.

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

Parameters
varA variable of rb_atomic_t
Returns
What was stored in varj

Definition at line 153 of file atomic.h.

◆ RUBY_ATOMIC_OR

#define RUBY_ATOMIC_OR (   var,
  val 
)    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
varA variable of rb_atomic_t.
valValue to mix.
Returns
void
Postcondition
var holds var | val.
Note
For portability, this macro can return void.

Definition at line 119 of file atomic.h.

◆ RUBY_ATOMIC_PTR_CAS

#define RUBY_ATOMIC_PTR_CAS (   var,
  oldval,
  newval 
)     RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (void *)(oldval), (void *)(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
varA variable of void*.
oldvalExpected value of var before the assignment.
newvalWhat you want to store at var.
Return values
oldvalSuccessful assignment (var is now newval).
otherwiseSomething else is at var; not updated.

Definition at line 343 of file atomic.h.

◆ RUBY_ATOMIC_PTR_EXCHANGE

#define RUBY_ATOMIC_PTR_EXCHANGE (   var,
  val 
)     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
varA variable of void *.
valValue to set.
Returns
What was stored in var before the assignment.
Postcondition
var holds val.

Definition at line 305 of file atomic.h.

◆ RUBY_ATOMIC_PTR_LOAD

#define RUBY_ATOMIC_PTR_LOAD (   var)     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
varA variable of void*
Returns
The value of var (without tearing)

Definition at line 316 of file atomic.h.

◆ RUBY_ATOMIC_PTR_SET

#define RUBY_ATOMIC_PTR_SET (   var,
  val 
)     rbimpl_atomic_ptr_set((volatile void **)&(var), (val))

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

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
varA variable of void*.
valValue to set.
Postcondition
var holds val.

Definition at line 329 of file atomic.h.

◆ RUBY_ATOMIC_SET

#define RUBY_ATOMIC_SET (   var,
  val 
)    rbimpl_atomic_set(&(var), (val))

Identical to RUBY_ATOMIC_EXCHANGE, except for the return type.

Parameters
varA variable of rb_atomic_t.
valValue to set.
Returns
void
Postcondition
var holds val.

Definition at line 163 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_ADD

#define RUBY_ATOMIC_SIZE_ADD (   var,
  val 
)    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
varA variable of size_t.
valValue to add.
Returns
void
Postcondition
var holds var + val.

Definition at line 275 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_CAS

#define RUBY_ATOMIC_SIZE_CAS (   var,
  oldval,
  newval 
)     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
varA variable of size_t.
oldvalExpected value of var before the assignment.
newvalWhat you want to store at var.
Return values
oldvalSuccessful assignment (var is now newval).
otherwiseSomething else is at var; not updated.

Definition at line 262 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_DEC

#define RUBY_ATOMIC_SIZE_DEC (   var)    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
varA variable of size_t.
Returns
void
Postcondition
var holds var - 1.

Definition at line 235 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_EXCHANGE

#define RUBY_ATOMIC_SIZE_EXCHANGE (   var,
  val 
)     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
varA variable of size_t.
valValue to set.
Returns
What was stored in var before the assignment.
Postcondition
var holds val.

Definition at line 248 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_FETCH_ADD

#define RUBY_ATOMIC_SIZE_FETCH_ADD (   var,
  val 
)    rbimpl_atomic_size_fetch_add(&(var), (val))

Identical to RUBY_ATOMIC_FETCH_ADD, except it expects its arguments to be 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
varA variable of size_t.
valValue to add.
Returns
What was stored in var before the addition.
Postcondition
var holds var + val.

Definition at line 213 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_INC

#define RUBY_ATOMIC_SIZE_INC (   var)    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
varA variable of size_t.
Returns
void
Postcondition
var holds var + 1.

Definition at line 224 of file atomic.h.

◆ RUBY_ATOMIC_SIZE_SUB

#define RUBY_ATOMIC_SIZE_SUB (   var,
  val 
)    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
varA variable of size_t.
valValue to subtract.
Returns
void
Postcondition
var holds var - val.

Definition at line 287 of file atomic.h.

◆ RUBY_ATOMIC_SUB

#define RUBY_ATOMIC_SUB (   var,
  val 
)    rbimpl_atomic_sub(&(var), (val))

Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type.

Parameters
varA variable of rb_atomic_t.
valValue to subtract.
Returns
void
Postcondition
var holds var - val.

Definition at line 183 of file atomic.h.

◆ RUBY_ATOMIC_VALUE_CAS

#define RUBY_ATOMIC_VALUE_CAS (   var,
  oldval,
  newval 
)     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
varA variable of void*.
oldvalExpected value of var before the assignment.
newvalWhat you want to store at var.
Return values
oldvalSuccessful assignment (var is now newval).
otherwiseSomething else is at var; not updated.

Definition at line 384 of file atomic.h.

◆ RUBY_ATOMIC_VALUE_EXCHANGE

#define RUBY_ATOMIC_VALUE_EXCHANGE (   var,
  val 
)     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
varA variable of VALUE.
valValue to set.
Returns
What was stored in var before the assignment.
Postcondition
var holds val.

Definition at line 370 of file atomic.h.

◆ RUBY_ATOMIC_VALUE_SET

#define RUBY_ATOMIC_VALUE_SET (   var,
  val 
)     rbimpl_atomic_value_set(&(var), (val))

Identical to RUBY_ATOMIC_SET, 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
varA variable of VALUE.
valValue to set.
Postcondition
var holds val.

Definition at line 356 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.