[libcxx-commits] [libcxx] fdf91c7 - [libc++][NFC] Introduce named states in std::call_once (#66289)

via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 15 07:14:17 PDT 2023


Author: Louis Dionne
Date: 2023-09-15T10:14:13-04:00
New Revision: fdf91c768e129488916afc0474fa765eaa863e39

URL: https://github.com/llvm/llvm-project/commit/fdf91c768e129488916afc0474fa765eaa863e39
DIFF: https://github.com/llvm/llvm-project/commit/fdf91c768e129488916afc0474fa765eaa863e39.diff

LOG: [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.

Added: 
    

Modified: 
    libcxx/include/__mutex/once_flag.h
    libcxx/src/mutex.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__mutex/once_flag.h b/libcxx/include/__mutex/once_flag.h
index 4d71cb38a1011ce..086f75ca4f81480 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 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;


        


More information about the libcxx-commits mailing list