diff --git a/src/cs_ident.cc b/src/cs_ident.cc index 27e475e..0caf17f 100644 --- a/src/cs_ident.cc +++ b/src/cs_ident.cc @@ -24,6 +24,13 @@ static inline void var_store(unsigned char *base, T v) noexcept { p->store(v); } +template +static inline T var_exchange(unsigned char const *base, T v) noexcept { + atomic_type *p{}; + std::memcpy(&p, &base, sizeof(void *)); + return p->exchange(v); +} + /* the ctors are non-atomic; that's okay, these are called during ident * creation before anything is stored, so there is no chance of data race */ @@ -60,16 +67,14 @@ static inline void var_save( ) noexcept { switch (v.type()) { case value_type::INTEGER: - var_store(top, var_load(fromp)); - var_store(fromp, 0); + var_store(top, var_exchange(fromp, 0)); return; case value_type::FLOAT: { using FST = typename var_value::FS; FST vs{}; float_type fv = 0; std::memcpy(&vs, &fv, sizeof(fv)); - var_store(top, var_load(fromp)); - var_store(fromp, vs); + var_store(top, var_exchange(fromp, vs)); return; } case value_type::STRING: { @@ -77,8 +82,9 @@ static inline void var_save( if (p) { str_managed_unref(p); } - var_store(top, var_load(fromp)); - var_store(fromp, nullptr); + var_store( + top, var_exchange(fromp, nullptr) + ); } default: break; diff --git a/src/cs_lock.hh b/src/cs_lock.hh index 420f4c0..8b80226 100644 --- a/src/cs_lock.hh +++ b/src/cs_lock.hh @@ -6,6 +6,8 @@ #if LIBCUBESCRIPT_CONF_THREAD_SAFE #include #include +#else +#include #endif namespace cubescript { @@ -27,6 +29,9 @@ struct atomic_type { void store(T v) { p_v = v; } + T exchange(T v) { + return std::exchange(p_v, v); + } }; #else