Skip to content

Commit a3c8abc

Browse files
committed
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.
1 parent a022a75 commit a3c8abc

2 files changed

Lines changed: 11 additions & 15 deletions

File tree

src/ds/flaglock.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace snmalloc
1717
* @brief flag
1818
* The underlying atomic field.
1919
*/
20-
std::atomic_flag flag = ATOMIC_FLAG_INIT;
20+
std::atomic_bool flag{false};
2121

2222
constexpr DebugFlagWord() = default;
2323

@@ -84,7 +84,7 @@ namespace snmalloc
8484
*/
8585
struct ReleaseFlagWord
8686
{
87-
std::atomic_flag flag = ATOMIC_FLAG_INIT;
87+
std::atomic_bool flag{false};
8888

8989
constexpr ReleaseFlagWord() = default;
9090

@@ -112,31 +112,26 @@ namespace snmalloc
112112
public:
113113
FlagLock(FlagWord& lock) : lock(lock)
114114
{
115-
while (lock.flag.test_and_set(std::memory_order_acquire))
115+
while (lock.flag.exchange(true, std::memory_order_acquire))
116116
{
117117
// assert_not_owned_by_current_thread is only called when the first
118118
// acquiring is failed; which means the lock is already held somewhere
119119
// else.
120120
lock.assert_not_owned_by_current_thread();
121-
#ifdef __cpp_lib_atomic_flag_test
122-
// acquire ordering because we need other thread's release to be
123-
// visible. This loop is better for spin-waiting because it won't issue
121+
// This loop is better for spin-waiting because it won't issue
124122
// expensive write operation (xchg for example).
125-
while (lock.flag.test(std::memory_order_acquire))
123+
while (lock.flag.load(std::memory_order_relaxed))
126124
{
127125
Aal::pause();
128126
}
129-
#else
130-
Aal::pause();
131-
#endif
132127
}
133128
lock.set_owner();
134129
}
135130

136131
~FlagLock()
137132
{
138133
lock.clear_owner();
139-
lock.flag.clear(std::memory_order_release);
134+
lock.flag.store(false, std::memory_order_release);
140135
}
141136
};
142137
} // namespace snmalloc

src/pal/pal_ds.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,10 @@ namespace snmalloc
142142

143143
void check(uint64_t time_ms)
144144
{
145-
static std::atomic_flag lock = ATOMIC_FLAG_INIT;
145+
static std::atomic_bool lock{false};
146146

147-
// Depulicate calls into here, and make single threaded.
148-
if (lock.test_and_set())
147+
// Deduplicate calls into here, and make single threaded.
148+
if (lock.exchange(true, std::memory_order_acquire))
149149
return;
150150

151151
timers.apply_all([time_ms](PalTimerObject* curr) {
@@ -156,7 +156,8 @@ namespace snmalloc
156156
curr->pal_notify(curr);
157157
}
158158
});
159-
lock.clear();
159+
160+
lock.store(false, std::memory_order_release);
160161
}
161162
};
162163
} // namespace snmalloc

0 commit comments

Comments
 (0)