Ruby
3.4.0dev (2024-11-05 revision 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"
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... | |
Atomic operations.
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. __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.
#define RUBY_ATOMIC_ADD | ( | var, | |
val | |||
) | rbimpl_atomic_add(&(var), (val)) |
Identical to RUBY_ATOMIC_FETCH_ADD, except for the return type.
var | A variable of rb_atomic_t. |
val | Value to add. |
var
holds var + val
. #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.
var | A variable of rb_atomic_t. |
oldval | Expected value of var before the assignment. |
newval | What you want to store at var . |
oldval | Successful assignment (var is now newval ). |
otherwise | Something else is at var ; not updated. |
#define RUBY_ATOMIC_DEC | ( | var | ) | rbimpl_atomic_dec(&(var)) |
Atomically decrements the value pointed by var
.
var | A variable of rb_atomic_t. |
var
holds var - 1
. #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.
var | A variable of rb_atomic_t. |
val | Value to set. |
var
before the assignment. var
holds val
. #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
.
var | A variable of rb_atomic_t. |
val | Value to add. |
var
before the addition. var
holds var + val
. #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
.
var | A variable of rb_atomic_t. |
val | Value to subtract. |
var
before the subtraction. var
holds var - val
. #define RUBY_ATOMIC_INC | ( | var | ) | rbimpl_atomic_inc(&(var)) |
Atomically increments the value pointed by var
.
var | A variable of rb_atomic_t. |
var
holds var + 1
. #define RUBY_ATOMIC_LOAD | ( | var | ) | rbimpl_atomic_load(&(var)) |
Atomic load.
This loads var
with an atomic intrinsic and returns its value.
var | A variable of rb_atomic_t |
var
j #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
.
var | A variable of rb_atomic_t. |
val | Value to mix. |
var
holds var | val
. #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.
var | A variable of void* . |
oldval | Expected value of var before the assignment. |
newval | What you want to store at var . |
oldval | Successful assignment (var is now newval ). |
otherwise | Something else is at var ; not updated. |
#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.
var | A variable of void * . |
val | Value to set. |
var
before the assignment. var
holds val
. #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.
var | A variable of void* |
var
(without tearing) #define RUBY_ATOMIC_SET | ( | var, | |
val | |||
) | rbimpl_atomic_set(&(var), (val)) |
Identical to RUBY_ATOMIC_EXCHANGE, except for the return type.
var | A variable of rb_atomic_t. |
val | Value to set. |
var
holds val
. #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.
var | A variable of size_t . |
val | Value to add. |
var
holds var + val
. #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.
var | A variable of size_t . |
oldval | Expected value of var before the assignment. |
newval | What you want to store at var . |
oldval | Successful assignment (var is now newval ). |
otherwise | Something else is at var ; not updated. |
#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.
var | A variable of size_t . |
var
holds var - 1
. #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.
var | A variable of size_t . |
val | Value to set. |
var
before the assignment. var
holds val
. #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.
var | A variable of size_t . |
var
holds var + 1
. #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.
var | A variable of size_t . |
val | Value to subtract. |
var
holds var - val
. #define RUBY_ATOMIC_SUB | ( | var, | |
val | |||
) | rbimpl_atomic_sub(&(var), (val)) |
Identical to RUBY_ATOMIC_FETCH_SUB, except for the return type.
var | A variable of rb_atomic_t. |
val | Value to subtract. |
var
holds var - val
. #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.
var | A variable of void* . |
oldval | Expected value of var before the assignment. |
newval | What you want to store at var . |
oldval | Successful assignment (var is now newval ). |
otherwise | Something else is at var ; not updated. |
#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.
var | A variable of VALUE. |
val | Value to set. |
var
before the assignment. var
holds val
. using rb_atomic_t = std::atomic<unsigned> |