From a3c8abc3c33d495ba50c17c315d6728ba58e745d Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Fri, 18 Mar 2022 14:50:58 +0000 Subject: [PATCH] Switch atomic_flag to atomic_bool The constructor for atomic_flag is challenging to use in a constexpr. It requires std::atomic_flag flag = ATOMIC_FLAG_INIT; which is not constexpr on some compilers in C++20. Switching to atomic_bool solves this problem. --- src/ds/flaglock.h | 17 ++++++----------- src/pal/pal_ds.h | 9 +++++---- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/ds/flaglock.h b/src/ds/flaglock.h index 6155d2b..c25f1ee 100644 --- a/src/ds/flaglock.h +++ b/src/ds/flaglock.h @@ -17,7 +17,7 @@ namespace snmalloc * @brief flag * The underlying atomic field. */ - std::atomic_flag flag = ATOMIC_FLAG_INIT; + std::atomic_bool flag{false}; constexpr DebugFlagWord() = default; @@ -84,7 +84,7 @@ namespace snmalloc */ struct ReleaseFlagWord { - std::atomic_flag flag = ATOMIC_FLAG_INIT; + std::atomic_bool flag{false}; constexpr ReleaseFlagWord() = default; @@ -112,23 +112,18 @@ namespace snmalloc public: FlagLock(FlagWord& lock) : lock(lock) { - while (lock.flag.test_and_set(std::memory_order_acquire)) + while (lock.flag.exchange(true, std::memory_order_acquire)) { // assert_not_owned_by_current_thread is only called when the first // acquiring is failed; which means the lock is already held somewhere // else. lock.assert_not_owned_by_current_thread(); -#ifdef __cpp_lib_atomic_flag_test - // acquire ordering because we need other thread's release to be - // visible. This loop is better for spin-waiting because it won't issue + // This loop is better for spin-waiting because it won't issue // expensive write operation (xchg for example). - while (lock.flag.test(std::memory_order_acquire)) + while (lock.flag.load(std::memory_order_relaxed)) { Aal::pause(); } -#else - Aal::pause(); -#endif } lock.set_owner(); } @@ -136,7 +131,7 @@ namespace snmalloc ~FlagLock() { lock.clear_owner(); - lock.flag.clear(std::memory_order_release); + lock.flag.store(false, std::memory_order_release); } }; } // namespace snmalloc diff --git a/src/pal/pal_ds.h b/src/pal/pal_ds.h index 543fb8a..d6197d1 100644 --- a/src/pal/pal_ds.h +++ b/src/pal/pal_ds.h @@ -142,10 +142,10 @@ namespace snmalloc void check(uint64_t time_ms) { - static std::atomic_flag lock = ATOMIC_FLAG_INIT; + static std::atomic_bool lock{false}; - // Depulicate calls into here, and make single threaded. - if (lock.test_and_set()) + // Deduplicate calls into here, and make single threaded. + if (lock.exchange(true, std::memory_order_acquire)) return; timers.apply_all([time_ms](PalTimerObject* curr) { @@ -156,7 +156,8 @@ namespace snmalloc curr->pal_notify(curr); } }); - lock.clear(); + + lock.store(false, std::memory_order_release); } }; } // namespace snmalloc