@@ -13,6 +13,7 @@ typedef unsigned int rb_atomic_t; /* Anything OK */
1313# define ATOMIC_DEC (var ) __sync_fetch_and_sub(&(var), 1)
1414# define ATOMIC_OR (var , val ) __sync_or_and_fetch(&(var), (val))
1515# define ATOMIC_EXCHANGE (var , val ) __sync_lock_test_and_set(&(var), (val))
16+ # define ATOMIC_CAS (var , oldval , newval ) __sync_val_compare_and_swap(&(var), (oldval), (newval))
1617
1718# define ATOMIC_SIZE_ADD (var , val ) __sync_fetch_and_add(&(var), (val))
1819# define ATOMIC_SIZE_SUB (var , val ) __sync_fetch_and_sub(&(var), (val))
@@ -49,7 +50,17 @@ rb_w32_atomic_or(volatile rb_atomic_t *var, rb_atomic_t val)
4950# define ATOMIC_OR (var , val ) _InterlockedOr(&(var), (val))
5051#endif
5152# define ATOMIC_EXCHANGE (var , val ) InterlockedExchange(&(var), (val))
53+ # define ATOMIC_CAS (var , oldval , newval ) InterlockedCompareExchange(&(var), (newval), (oldval))
5254
55+ # if defined _MSC_VER && _MSC_VER <= 1200
56+ static inline rb_atomic_t
57+ rb_w32_atomic_cas (volatile rb_atomic_t * var , rb_atomic_t oldval , rb_atomic_t newval )
58+ {
59+ return (rb_atomic_t )InterlockedCompareExchange ((PVOID * )var , (PVOID )newval , (PVOID )oldval );
60+ }
61+ # undef ATOMIC_CAS
62+ # define ATOMIC_CAS (var , oldval , newval ) rb_w32_atomic_cas(&(var), (oldval), (newval))
63+ # endif
5364# ifdef _M_AMD64
5465# define ATOMIC_SIZE_ADD (var , val ) InterlockedExchangeAdd64(&(var), (val))
5566# define ATOMIC_SIZE_SUB (var , val ) InterlockedExchangeAdd64(&(var), -(val))
@@ -74,6 +85,7 @@ typedef unsigned int rb_atomic_t;
7485# define ATOMIC_DEC (var ) atomic_dec_uint(&(var))
7586# define ATOMIC_OR (var , val ) atomic_or_uint(&(var), (val))
7687# define ATOMIC_EXCHANGE (var , val ) atomic_swap_uint(&(var), (val))
88+ # define ATOMIC_CAS (var , oldval , newval ) atomic_cas_uint(&(var), (oldval), (newval))
7789
7890# if SIZEOF_SIZE_T == SIZEOF_LONG
7991# define ATOMIC_SIZE_ADD (var , val ) atomic_add_long(&(var), (val))
@@ -93,12 +105,16 @@ typedef unsigned int rb_atomic_t;
93105typedef int rb_atomic_t ;
94106#define NEED_RUBY_ATOMIC_EXCHANGE
95107extern rb_atomic_t ruby_atomic_exchange (rb_atomic_t * ptr , rb_atomic_t val );
108+ extern rb_atomic_t ruby_atomic_compare_and_swap (rb_atomic_t * ptr ,
109+ rb_atomic_t cmp ,
110+ rb_atomic_t newval );
96111
97112# define ATOMIC_SET (var , val ) (void)((var) = (val))
98113# define ATOMIC_INC (var ) ((var)++)
99114# define ATOMIC_DEC (var ) ((var)--)
100115# define ATOMIC_OR (var , val ) ((var) |= (val))
101116# define ATOMIC_EXCHANGE (var , val ) ruby_atomic_exchange(&(var), (val))
117+ # define ATOMIC_CAS (var , oldval , newval ) ruby_atomic_compare_and_swap(&(var), (oldval), (newval))
102118
103119# define ATOMIC_SIZE_ADD (var , val ) (void)((var) += (val))
104120# define ATOMIC_SIZE_SUB (var , val ) (void)((var) -= (val))
0 commit comments