Skip to content

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Sep 13, 2023

This idea is extracted from https://reviews.llvm.org/D112319. It makes the code easier to read but doesn't otherwise change any functionality.

@ldionne ldionne requested a review from a team as a code owner September 13, 2023 20:49
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 13, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 13, 2023

@llvm/pr-subscribers-libcxx

Changes This idea is extracted from https://reviews.llvm.org/D112319. It makes the code easier to read but doesn't otherwise change any functionality. -- Full diff: https://github.com//pull/66289.diff

2 Files Affected:

  • (modified) libcxx/include/__mutex/once_flag.h (+7-4)
  • (modified) libcxx/src/mutex.cpp (+9-9)
diff --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h
index 4d71cb38a1011ce..ea5254200462c94 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,9 @@ 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 +120,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 +132,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 +140,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 b3b84c4dc430dc7..1378e8872b2712d 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;

This idea is extracted from https://reviews.llvm.org/D112319. It makes
the code easier to read but doesn't otherwise change any functionality.
@ldionne ldionne force-pushed the review/refactor-once_flag branch from 799a6d8 to 6951dad Compare September 14, 2023 12:29
@ldionne ldionne merged commit fdf91c7 into llvm:main Sep 15, 2023
@ldionne ldionne deleted the review/refactor-once_flag branch September 15, 2023 14:14
ZijunZhaoCCK pushed a commit to ZijunZhaoCCK/llvm-project that referenced this pull request Sep 19, 2023
This idea is extracted from https://reviews.llvm.org/D112319. It makes
the code easier to read but doesn't otherwise change any functionality.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants