aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Dionne <ldionne.2@gmail.com>2023-09-15 10:14:13 -0400
committerGitHub <noreply@github.com>2023-09-15 10:14:13 -0400
commitfdf91c768e129488916afc0474fa765eaa863e39 (patch)
tree66c1b95c92713c022f7227af8e068490d93a8df4
parentde6a919f77f2a63f9e7f86ec51cf8a508fedf188 (diff)
downloadllvm-fdf91c768e129488916afc0474fa765eaa863e39.zip
llvm-fdf91c768e129488916afc0474fa765eaa863e39.tar.gz
llvm-fdf91c768e129488916afc0474fa765eaa863e39.tar.bz2
[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.
-rw-r--r--libcxx/include/__mutex/once_flag.h12
-rw-r--r--libcxx/src/mutex.cpp18
2 files changed, 17 insertions, 13 deletions
diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h
index 4d71cb3..086f75c 100644
--- a/libcxx/include/__mutex/once_flag.h
+++ b/libcxx/include/__mutex/once_flag.h
@@ -45,7 +45,7 @@ _LIBCPP_HIDE_FROM_ABI void call_once(once_flag&, const _Callable&);
#endif // _LIBCPP_CXX03_LANG
struct _LIBCPP_TEMPLATE_VIS once_flag {
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(0) {}
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR once_flag() _NOEXCEPT : __state_(_Unset) {}
once_flag(const once_flag&) = delete;
once_flag& operator=(const once_flag&) = delete;
@@ -55,6 +55,10 @@ struct _LIBCPP_TEMPLATE_VIS once_flag {
typedef unsigned long _State_type;
#endif
+ static const _State_type _Unset = 0;
+ static const _State_type _Pending = 1;
+ static const _State_type _Complete = ~_State_type(0);
+
private:
_State_type __state_;
@@ -117,7 +121,7 @@ _LIBCPP_EXPORTED_FROM_ABI void __call_once(volatile once_flag::_State_type&, voi
template <class _Callable, class... _Args>
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) {
- if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
+ if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
typedef tuple<_Callable&&, _Args&&...> _Gp;
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...);
__call_once_param<_Gp> __p(__f);
@@ -129,7 +133,7 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable&& __fun
template <class _Callable>
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func) {
- if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
+ if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
__call_once_param<_Callable> __p(__func);
std::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>);
}
@@ -137,7 +141,7 @@ inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, _Callable& __func
template <class _Callable>
inline _LIBCPP_HIDE_FROM_ABI void call_once(once_flag& __flag, const _Callable& __func) {
- if (__libcpp_acquire_load(&__flag.__state_) != ~once_flag::_State_type(0)) {
+ if (__libcpp_acquire_load(&__flag.__state_) != once_flag::_Complete) {
__call_once_param<const _Callable> __p(__func);
std::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>);
}
diff --git a/libcxx/src/mutex.cpp b/libcxx/src/mutex.cpp
index b3b84c4..1378e88 100644
--- a/libcxx/src/mutex.cpp
+++ b/libcxx/src/mutex.cpp
@@ -205,39 +205,39 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
void (*func)(void*))
{
#if defined(_LIBCPP_HAS_NO_THREADS)
- if (flag == 0)
+ if (flag == once_flag::_Unset)
{
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
- flag = 1;
+ flag = once_flag::_Pending;
func(arg);
- flag = ~once_flag::_State_type(0);
+ flag = once_flag::_Complete;
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
}
catch (...)
{
- flag = 0;
+ flag = once_flag::_Unset;
throw;
}
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
}
#else // !_LIBCPP_HAS_NO_THREADS
__libcpp_mutex_lock(&mut);
- while (flag == 1)
+ while (flag == once_flag::_Pending)
__libcpp_condvar_wait(&cv, &mut);
- if (flag == 0)
+ if (flag == once_flag::_Unset)
{
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
- __libcpp_relaxed_store(&flag, once_flag::_State_type(1));
+ __libcpp_relaxed_store(&flag, once_flag::_Pending);
__libcpp_mutex_unlock(&mut);
func(arg);
__libcpp_mutex_lock(&mut);
- __libcpp_atomic_store(&flag, ~once_flag::_State_type(0),
+ __libcpp_atomic_store(&flag, once_flag::_Complete,
_AO_Release);
__libcpp_mutex_unlock(&mut);
__libcpp_condvar_broadcast(&cv);
@@ -246,7 +246,7 @@ void __call_once(volatile once_flag::_State_type& flag, void* arg,
catch (...)
{
__libcpp_mutex_lock(&mut);
- __libcpp_relaxed_store(&flag, once_flag::_State_type(0));
+ __libcpp_relaxed_store(&flag, once_flag::_Unset);
__libcpp_mutex_unlock(&mut);
__libcpp_condvar_broadcast(&cv);
throw;