Ruby  3.4.0dev (2024-11-05 revision 348a53415339076afc4a02fcd09f3ae36e9c4c61)
Macros | Typedefs
atomic.h File Reference

(348a53415339076afc4a02fcd09f3ae36e9c4c61)

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. More...
 
#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. More...
 
#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. More...
 
#define RUBY_ATOMIC_EXCHANGE(var, val)   rbimpl_atomic_exchange(&(var), (val))
 Atomically replaces the value pointed by var with val. More...
 
#define RUBY_ATOMIC_CAS(var, oldval, newval)    rbimpl_atomic_cas(&(var), (oldval), (newval))
 Atomic compare-and-swap. More...
 
#define RUBY_ATOMIC_LOAD(var)   rbimpl_atomic_load(&(var))
 Atomic load. More...
 
#define RUBY_ATOMIC_SET(var, val)   rbimpl_atomic_set(&(var), (val))
 Identical to RUBY_ATOMIC_EXCHANGE, except for the return type. More...
 
#define RUBY_ATOMIC_ADD(var, val)   rbimpl_atomic_add(&(var), (val))
 Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type. More...
 
#define RUBY_ATOMIC_SUB(var, val)   rbimpl_atomic_sub(&(var), (val))
 Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type. More...
 
#define RUBY_ATOMIC_INC(var)   rbimpl_atomic_inc(&(var))
 Atomically increments the value pointed by var. More...
 
#define RUBY_ATOMIC_DEC(var)   rbimpl_atomic_dec(&(var))
 Atomically decrements the value pointed by var. More...
 
#define RUBY_ATOMIC_SIZE_INC(var)   rbimpl_atomic_size_inc(&(var))
 Identical to RUBY_ATOMIC_INC, except it expects its argument is size_t. More...
 
#define RUBY_ATOMIC_SIZE_DEC(var)   rbimpl_atomic_size_dec(&(var))
 Identical to RUBY_ATOMIC_DEC, except it expects its argument is size_t. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#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*. More...
 
#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*. More...
 
#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*. More...
 
#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. More...
 
#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. More...
 

Typedefs

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

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 170 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 140 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 198 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 127 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 93 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 104 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 189 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 150 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 116 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 315 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 290 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 301 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 160 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 260 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 247 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 220 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 233 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 209 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 272 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 180 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 343 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 329 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.