LCOV - code coverage report
Current view: top level - usr/include/boost/thread/pthread - once_atomic.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 6 9 66.7 %
Date: 2022-12-08 13:48:47 Functions: 1 3 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #ifndef BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
       2             : #define BOOST_THREAD_PTHREAD_ONCE_ATOMIC_HPP
       3             : 
       4             : //  once.hpp
       5             : //
       6             : //  (C) Copyright 2013 Andrey Semashev
       7             : //  (C) Copyright 2013 Vicente J. Botet Escriba
       8             : //
       9             : //  Distributed under the Boost Software License, Version 1.0. (See
      10             : //  accompanying file LICENSE_1_0.txt or copy at
      11             : //  http://www.boost.org/LICENSE_1_0.txt)
      12             : 
      13             : #include <boost/thread/detail/config.hpp>
      14             : 
      15             : #include <boost/cstdint.hpp>
      16             : #include <boost/thread/detail/move.hpp>
      17             : #include <boost/thread/detail/invoke.hpp>
      18             : #include <boost/core/no_exceptions_support.hpp>
      19             : #include <boost/bind.hpp>
      20             : #include <boost/atomic.hpp>
      21             : 
      22             : #include <boost/config/abi_prefix.hpp>
      23             : 
      24             : namespace boost
      25             : {
      26             : 
      27             :   struct once_flag;
      28             : 
      29             :   namespace thread_detail
      30             :   {
      31             : 
      32             : #if BOOST_ATOMIC_INT_LOCK_FREE == 2
      33             :     typedef unsigned int atomic_int_type;
      34             : #elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
      35             :     typedef unsigned short atomic_int_type;
      36             : #elif BOOST_ATOMIC_CHAR_LOCK_FREE == 2
      37             :     typedef unsigned char atomic_int_type;
      38             : #elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
      39             :     typedef unsigned long atomic_int_type;
      40             : #elif defined(BOOST_HAS_LONG_LONG) && BOOST_ATOMIC_LLONG_LOCK_FREE == 2
      41             :     typedef ulong_long_type atomic_int_type;
      42             : #else
      43             :     // All tested integer types are not atomic, the spinlock pool will be used
      44             :     typedef unsigned int atomic_int_type;
      45             : #endif
      46             : 
      47             :     typedef boost::atomic<atomic_int_type> atomic_type;
      48             : 
      49             :     BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
      50             :     BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
      51             :     BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
      52             :     inline atomic_type& get_atomic_storage(once_flag& flag)  BOOST_NOEXCEPT;
      53             :   }
      54             : 
      55             : #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
      56             : 
      57             :   struct once_flag
      58             :   {
      59             :     BOOST_THREAD_NO_COPYABLE(once_flag)
      60             :     BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT : storage(0)
      61             :     {
      62             :     }
      63             : 
      64             :   private:
      65             :     thread_detail::atomic_type storage;
      66             : 
      67             :     friend BOOST_THREAD_DECL bool thread_detail::enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
      68             :     friend BOOST_THREAD_DECL void thread_detail::commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
      69             :     friend BOOST_THREAD_DECL void thread_detail::rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
      70             :     friend thread_detail::atomic_type& thread_detail::get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
      71             :   };
      72             : 
      73             : #define BOOST_ONCE_INIT boost::once_flag()
      74             : 
      75             :   namespace thread_detail
      76             :   {
      77             :     inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
      78             :     {
      79             :       //return reinterpret_cast< atomic_type& >(flag.storage);
      80             :       return flag.storage;
      81             :     }
      82             :   }
      83             : 
      84             : #else // BOOST_THREAD_PROVIDES_ONCE_CXX11
      85             :   struct once_flag
      86             :   {
      87             :     // The thread_detail::atomic_int_type storage is marked
      88             :     // with this attribute in order to let the compiler know that it will alias this member
      89             :     // and silence compilation warnings.
      90             :     BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
      91             :   };
      92             : 
      93             :   #define BOOST_ONCE_INIT {0}
      94             : 
      95             :   namespace thread_detail
      96             :   {
      97             :     inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
      98             :     {
      99             :       return reinterpret_cast< atomic_type& >(flag.storage);
     100             :     }
     101             : 
     102             :   }
     103             : 
     104             : #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
     105             : 
     106             : #if defined BOOST_THREAD_PROVIDES_INVOKE
     107             : #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
     108             : #define BOOST_THREAD_INVOKE_RET_VOID_CALL
     109             : #elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
     110             : #define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
     111             : #define BOOST_THREAD_INVOKE_RET_VOID_CALL
     112             : #else
     113             : #define BOOST_THREAD_INVOKE_RET_VOID boost::bind
     114             : #define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
     115             : #endif
     116             : 
     117             : 
     118             : #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
     119             : 
     120             :   template<typename Function, class ...ArgTypes>
     121         357 :   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
     122             :   {
     123         357 :     if (thread_detail::enter_once_region(flag))
     124             :     {
     125             :       BOOST_TRY
     126             :       {
     127         357 :         BOOST_THREAD_INVOKE_RET_VOID(
     128         357 :                         thread_detail::decay_copy(boost::forward<Function>(f)),
     129             :                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
     130             :         ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     131             :       }
     132           0 :       BOOST_CATCH (...)
     133             :       {
     134           0 :         thread_detail::rollback_once_region(flag);
     135           0 :         BOOST_RETHROW
     136             :       }
     137             :       BOOST_CATCH_END
     138         357 :       thread_detail::commit_once_region(flag);
     139             :     }
     140         357 :   }
     141             : #else
     142             :   template<typename Function>
     143             :   inline void call_once(once_flag& flag, Function f)
     144             :   {
     145             :     if (thread_detail::enter_once_region(flag))
     146             :     {
     147             :       BOOST_TRY
     148             :       {
     149             :         f();
     150             :       }
     151             :       BOOST_CATCH (...)
     152             :       {
     153             :         thread_detail::rollback_once_region(flag);
     154             :         BOOST_RETHROW
     155             :       }
     156             :       BOOST_CATCH_END
     157             :       thread_detail::commit_once_region(flag);
     158             :     }
     159             :   }
     160             : 
     161             :   template<typename Function, typename T1>
     162             :   inline void call_once(once_flag& flag, Function f, T1 p1)
     163             :   {
     164             :     if (thread_detail::enter_once_region(flag))
     165             :     {
     166             :       BOOST_TRY
     167             :       {
     168             :         BOOST_THREAD_INVOKE_RET_VOID(f, p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     169             :       }
     170             :       BOOST_CATCH (...)
     171             :       {
     172             :         thread_detail::rollback_once_region(flag);
     173             :         BOOST_RETHROW
     174             :       }
     175             :       BOOST_CATCH_END
     176             :       thread_detail::commit_once_region(flag);
     177             :     }
     178             :   }
     179             : 
     180             :   template<typename Function, typename T1, typename T2>
     181             :   inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2)
     182             :   {
     183             :     if (thread_detail::enter_once_region(flag))
     184             :     {
     185             :       BOOST_TRY
     186             :       {
     187             :         BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     188             :       }
     189             :       BOOST_CATCH (...)
     190             :       {
     191             :         thread_detail::rollback_once_region(flag);
     192             :         BOOST_RETHROW
     193             :       }
     194             :       BOOST_CATCH_END
     195             :       thread_detail::commit_once_region(flag);
     196             :     }
     197             :   }
     198             : 
     199             :   template<typename Function, typename T1, typename T2, typename T3>
     200             :   inline void call_once(once_flag& flag, Function f, T1 p1, T2 p2, T3 p3)
     201             :   {
     202             :     if (thread_detail::enter_once_region(flag))
     203             :     {
     204             :       BOOST_TRY
     205             :       {
     206             :         BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     207             :       }
     208             :       BOOST_CATCH (...)
     209             :       {
     210             :         thread_detail::rollback_once_region(flag);
     211             :         BOOST_RETHROW
     212             :       }
     213             :       BOOST_CATCH_END
     214             :       thread_detail::commit_once_region(flag);
     215             :     }
     216             :   }
     217             : #if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
     218             :   template<typename Function>
     219             :   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
     220             :   {
     221             :     if (thread_detail::enter_once_region(flag))
     222             :     {
     223             :       BOOST_TRY
     224             :       {
     225             :         f();
     226             :       }
     227             :       BOOST_CATCH (...)
     228             :       {
     229             :         thread_detail::rollback_once_region(flag);
     230             :         BOOST_RETHROW
     231             :       }
     232             :       BOOST_CATCH_END
     233             :       thread_detail::commit_once_region(flag);
     234             :     }
     235             :   }
     236             : 
     237             :   template<typename Function, typename T1>
     238             :   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1)
     239             :   {
     240             :     if (thread_detail::enter_once_region(flag))
     241             :     {
     242             :       BOOST_TRY
     243             :       {
     244             :         BOOST_THREAD_INVOKE_RET_VOID(
     245             :             thread_detail::decay_copy(boost::forward<Function>(f)),
     246             :             thread_detail::decay_copy(boost::forward<T1>(p1))
     247             :         ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     248             :       }
     249             :       BOOST_CATCH (...)
     250             :       {
     251             :         thread_detail::rollback_once_region(flag);
     252             :         BOOST_RETHROW
     253             :       }
     254             :       BOOST_CATCH_END
     255             :       thread_detail::commit_once_region(flag);
     256             :     }
     257             :   }
     258             :   template<typename Function, typename T1, typename T2>
     259             :   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2)
     260             :   {
     261             :     if (thread_detail::enter_once_region(flag))
     262             :     {
     263             :       BOOST_TRY
     264             :       {
     265             :         BOOST_THREAD_INVOKE_RET_VOID(
     266             :             thread_detail::decay_copy(boost::forward<Function>(f)),
     267             :             thread_detail::decay_copy(boost::forward<T1>(p1)),
     268             :             thread_detail::decay_copy(boost::forward<T1>(p2))
     269             :         ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     270             :       }
     271             :       BOOST_CATCH (...)
     272             :       {
     273             :         thread_detail::rollback_once_region(flag);
     274             :         BOOST_RETHROW
     275             :       }
     276             :       BOOST_CATCH_END
     277             :       thread_detail::commit_once_region(flag);
     278             :     }
     279             :   }
     280             :   template<typename Function, typename T1, typename T2, typename T3>
     281             :   inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
     282             :   {
     283             :     if (thread_detail::enter_once_region(flag))
     284             :     {
     285             :       BOOST_TRY
     286             :       {
     287             :         BOOST_THREAD_INVOKE_RET_VOID(
     288             :             thread_detail::decay_copy(boost::forward<Function>(f)),
     289             :             thread_detail::decay_copy(boost::forward<T1>(p1)),
     290             :             thread_detail::decay_copy(boost::forward<T1>(p2)),
     291             :             thread_detail::decay_copy(boost::forward<T1>(p3))
     292             :         ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
     293             : 
     294             :       }
     295             :       BOOST_CATCH (...)
     296             :       {
     297             :         thread_detail::rollback_once_region(flag);
     298             :         BOOST_RETHROW
     299             :       }
     300             :       BOOST_CATCH_END
     301             :       thread_detail::commit_once_region(flag);
     302             :     }
     303             :   }
     304             : 
     305             : #endif // __SUNPRO_CC
     306             : 
     307             : #endif
     308             : }
     309             : 
     310             : #include <boost/config/abi_suffix.hpp>
     311             : 
     312             : #endif
     313             : 

Generated by: LCOV version 1.14