зеркало из https://github.com/github/ruby.git
Add RUBY_ATOMIC_{PTR_,}FETCH macros for atomic loads
This can already be emulated by doing an atomic fetch_add of zero, but this is more explicit. [Bug #19994]
This commit is contained in:
Родитель
6e8ad7497e
Коммит
aecbd66742
|
@ -138,6 +138,15 @@ typedef unsigned int rb_atomic_t;
|
|||
#define RUBY_ATOMIC_CAS(var, oldval, newval) \
|
||||
rbimpl_atomic_cas(&(var), (oldval), (newval))
|
||||
|
||||
/**
|
||||
* Atomic load. This loads `var` with an atomic intrinsic and returns
|
||||
* its value.
|
||||
*
|
||||
* @param var A variable of ::rb_atomic_t
|
||||
* @return What was stored in `var`j
|
||||
*/
|
||||
#define RUBY_ATOMIC_LOAD(var) rbimpl_atomic_load(&(var))
|
||||
|
||||
/**
|
||||
* Identical to #RUBY_ATOMIC_EXCHANGE, except for the return type.
|
||||
*
|
||||
|
@ -279,6 +288,17 @@ typedef unsigned int rb_atomic_t;
|
|||
#define RUBY_ATOMIC_PTR_EXCHANGE(var, val) \
|
||||
RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val))
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param var A variable of `void*`
|
||||
* @return The value of `var` (without tearing)
|
||||
*/
|
||||
#define RUBY_ATOMIC_PTR_LOAD(var) \
|
||||
RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var))
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -746,6 +766,21 @@ rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val)
|
|||
return RBIMPL_CAST((VALUE)sret);
|
||||
}
|
||||
|
||||
RBIMPL_ATTR_ARTIFICIAL()
|
||||
RBIMPL_ATTR_NOALIAS()
|
||||
RBIMPL_ATTR_NONNULL((1))
|
||||
static inline rb_atomic_t
|
||||
rbimpl_atomic_load(volatile rb_atomic_t *ptr)
|
||||
{
|
||||
#if 0
|
||||
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
|
||||
#else
|
||||
return rbimpl_atomic_fetch_add(ptr, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
RBIMPL_ATTR_ARTIFICIAL()
|
||||
RBIMPL_ATTR_NOALIAS()
|
||||
RBIMPL_ATTR_NONNULL((1))
|
||||
|
@ -872,6 +907,22 @@ rbimpl_atomic_ptr_cas(void **ptr, const void *oldval, const void *newval)
|
|||
#endif
|
||||
}
|
||||
|
||||
RBIMPL_ATTR_ARTIFICIAL()
|
||||
RBIMPL_ATTR_NOALIAS()
|
||||
RBIMPL_ATTR_NONNULL((1))
|
||||
static inline void *
|
||||
rbimpl_atomic_ptr_load(void **ptr)
|
||||
{
|
||||
#if 0
|
||||
|
||||
#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
|
||||
return __atomic_load_n(ptr, __ATOMIC_SEQ_CST);
|
||||
#else
|
||||
void *val = *ptr;
|
||||
return rbimpl_atomic_ptr_cas(ptr, val, val);
|
||||
#endif
|
||||
}
|
||||
|
||||
RBIMPL_ATTR_ARTIFICIAL()
|
||||
RBIMPL_ATTR_NOALIAS()
|
||||
RBIMPL_ATTR_NONNULL((1))
|
||||
|
|
Загрузка…
Ссылка в новой задаче