How is std::atomic<>
compare_exchange() related and translated to/from MS InterlockedCompareExchange64 on a non-atomic value? Are there performance or semantics differences?
For example, are these codes equivalent?
edit : David Haim pointed out that it should have been int64_t atomic_inc_ms(volatile int64_t& val, int64_t less_than)
int64_t atomic_inc_ms(int64_t& val, int64_t less_than) {
int64_t new_val;
int64_t old_val = val;
while(true)
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
int64_t got_val = InterlockedCompareExchange64(&val,new_val,old_val);
if(got_val == old_val) break;
old_val = got;
}
return new_val;
}
and
int64_t atomic_inc(std::atomic<int64_t>& val, int64_t less_than) {
int64_t new_val;
int64_t old_val = val.load();
do
{
if (old_val > less_than) return old_val;
new_val = old_val + 1;
} while (!val.compare_exchange_weak(old_val, new_val));
return new_val;
}
A concern is the line int64_t old_val = val;
with no explicit atomic load.
The example is that of Is there atomic increment with the check preconditions, that the atomic value was less than the specified value? and is close to the text book example on how to use compare_exchange_weak
.
Are compare_exchange_weak
and compare_exchange
, semantically equivalent to
InterlockedCompareExchangeAcquire64
and InterlockedCompareExchange64
?