Skip to content

Commit fdf91c7

Browse files
authored
[libc++][NFC] Introduce named states in std::call_once (#66289)
This idea is extracted from https://reviews.llvm.org/D112319. It makes the code easier to read but doesn't otherwise change any functionality.
1 parent de6a919 commit fdf91c7

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

libcxx/include/__mutex/once_flag.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);
4545
#endif // _LIBCPP_CXX03_LANG
4646

4747
struct _LIBCPP_TEMPLATE_VIS once_flag {
48-
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(0) {}
48+
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(_Unset) {}
4949
once_flag(const once_flag&) = delete;
5050
once_flag& operator=(const once_flag&) = delete;
5151

@@ -55,6 +55,10 @@ struct _LIBCPP_TEMPLATE_VIS once_flag {
5555
typedef unsigned long _State_type;
5656
#endif
5757

58+
static const _State_type _Unset = 0;
59+
static const _State_type _Pending = 1;
60+
static const _State_type _Complete = ~_State_type(0);
61+
5862
private:
5963
_State_type __state_;
6064

@@ -117,7 +121,7 @@ _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, voi
117121

118122
template <class _Callable, class... _Args>
119123
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) {
120-
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
124+
if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
121125
typedef tuple<_Callable&&, _Args&&...> _Gp;
122126
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
123127
__call_once_param<_Gp> __p(__f);
@@ -129,15 +133,15 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __fun
129133

130134
template <class _Callable>
131135
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {
132-
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
136+
if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
133137
__call_once_param<_Callable> __p(__func);
134138
std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
135139
}
136140
}
137141

138142
template <class _Callable>
139143
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {
140-
if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
144+
if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
141145
__call_once_param<const _Callable> __p(__func);
142146
std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
143147
}

libcxx/src/mutex.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -205,39 +205,39 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
205205
void (*func)(void*))
206206
{
207207
#if defined(_LIBCPP_HAS_NO_THREADS)
208-
if (flag == 0)
208+
if (flag == once_flag::_Unset)
209209
{
210210
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
211211
try
212212
{
213213
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
214-
flag = 1;
214+
flag = once_flag::_Pending;
215215
func(arg);
216-
flag = ~once_flag::_State_type(0);
216+
flag = once_flag::_Complete;
217217
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
218218
}
219219
catch (...)
220220
{
221-
flag = 0;
221+
flag = once_flag::_Unset;
222222
throw;
223223
}
224224
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
225225
}
226226
#else // !_LIBCPP_HAS_NO_THREADS
227227
__libcpp_mutex_lock(&mut);
228-
while (flag == 1)
228+
while (flag == once_flag::_Pending)
229229
__libcpp_condvar_wait(&cv, &mut);
230-
if (flag == 0)
230+
if (flag == once_flag::_Unset)
231231
{
232232
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
233233
try
234234
{
235235
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
236-
__libcpp_relaxed_store(&flag, once_flag::_State_type(1));
236+
__libcpp_relaxed_store(&flag, once_flag::_Pending);
237237
__libcpp_mutex_unlock(&mut);
238238
func(arg);
239239
__libcpp_mutex_lock(&mut);
240-
__libcpp_atomic_store(&flag, ~once_flag::_State_type(0),
240+
__libcpp_atomic_store(&flag, once_flag::_Complete,
241241
_AO_Release);
242242
__libcpp_mutex_unlock(&mut);
243243
__libcpp_condvar_broadcast(&cv);
@@ -246,7 +246,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
246246
catch (...)
247247
{
248248
__libcpp_mutex_lock(&mut);
249-
__libcpp_relaxed_store(&flag, once_flag::_State_type(0));
249+
__libcpp_relaxed_store(&flag, once_flag::_Unset);
250250
__libcpp_mutex_unlock(&mut);
251251
__libcpp_condvar_broadcast(&cv);
252252
throw;

0 commit comments

Comments
 (0)