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.
This commit is contained in:
Matthew Parkinson
2022-03-18 14:50:58 +00:00
committed by Matthew Parkinson
parent a022a75b91
commit a3c8abc3c3
2 changed files with 11 additions and 15 deletions

View File

@@ -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

View File

@@ -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