LCOV - code coverage report
Current view: top level - usr/include/c++/9/ext - concurrence.h (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 8 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Support for concurrent programing -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2003-2019 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @file ext/concurrence.h
      26             :  *  This file is a GNU extension to the Standard C++ Library.
      27             :  */
      28             : 
      29             : #ifndef _CONCURRENCE_H
      30             : #define _CONCURRENCE_H 1
      31             : 
      32             : #pragma GCC system_header
      33             : 
      34             : #include <exception>
      35             : #include <bits/gthr.h> 
      36             : #include <bits/functexcept.h>
      37             : #include <bits/cpp_type_traits.h>
      38             : #include <ext/type_traits.h>
      39             : 
      40             : namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
      41             : {
      42             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      43             : 
      44             :   // Available locking policies:
      45             :   // _S_single    single-threaded code that doesn't need to be locked.
      46             :   // _S_mutex     multi-threaded code that requires additional support
      47             :   //              from gthr.h or abstraction layers in concurrence.h.
      48             :   // _S_atomic    multi-threaded code using atomic operations.
      49             :   enum _Lock_policy { _S_single, _S_mutex, _S_atomic }; 
      50             : 
      51             :   // Compile time constant that indicates prefered locking policy in
      52             :   // the current configuration.
      53             :   static const _Lock_policy __default_lock_policy = 
      54             : #ifndef __GTHREADS
      55             :   _S_single;
      56             : #elif defined _GLIBCXX_HAVE_ATOMIC_LOCK_POLICY
      57             :   _S_atomic;
      58             : #else
      59             :   _S_mutex;
      60             : #endif
      61             : 
      62             :   // NB: As this is used in libsupc++, need to only depend on
      63             :   // exception. No stdexception classes, no use of std::string.
      64             :   class __concurrence_lock_error : public std::exception
      65             :   {
      66             :   public:
      67             :     virtual char const*
      68           0 :     what() const throw()
      69           0 :     { return "__gnu_cxx::__concurrence_lock_error"; }
      70             :   };
      71             : 
      72             :   class __concurrence_unlock_error : public std::exception
      73             :   {
      74             :   public:
      75             :     virtual char const*
      76           0 :     what() const throw()
      77           0 :     { return "__gnu_cxx::__concurrence_unlock_error"; }
      78             :   };
      79             : 
      80             :   class __concurrence_broadcast_error : public std::exception
      81             :   {
      82             :   public:
      83             :     virtual char const*
      84           0 :     what() const throw()
      85           0 :     { return "__gnu_cxx::__concurrence_broadcast_error"; }
      86             :   };
      87             : 
      88             :   class __concurrence_wait_error : public std::exception
      89             :   {
      90             :   public:
      91             :     virtual char const*
      92           0 :     what() const throw()
      93           0 :     { return "__gnu_cxx::__concurrence_wait_error"; }
      94             :   };
      95             : 
      96             :   // Substitute for concurrence_error object in the case of -fno-exceptions.
      97             :   inline void
      98             :   __throw_concurrence_lock_error()
      99             :   { _GLIBCXX_THROW_OR_ABORT(__concurrence_lock_error()); }
     100             : 
     101             :   inline void
     102             :   __throw_concurrence_unlock_error()
     103             :   { _GLIBCXX_THROW_OR_ABORT(__concurrence_unlock_error()); }
     104             : 
     105             : #ifdef __GTHREAD_HAS_COND
     106             :   inline void
     107             :   __throw_concurrence_broadcast_error()
     108             :   { _GLIBCXX_THROW_OR_ABORT(__concurrence_broadcast_error()); }
     109             : 
     110             :   inline void
     111             :   __throw_concurrence_wait_error()
     112             :   { _GLIBCXX_THROW_OR_ABORT(__concurrence_wait_error()); }
     113             : #endif
     114             :  
     115             :   class __mutex 
     116             :   {
     117             :   private:
     118             : #if __GTHREADS && defined __GTHREAD_MUTEX_INIT
     119             :     __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT;
     120             : #else
     121             :     __gthread_mutex_t _M_mutex;
     122             : #endif
     123             : 
     124             :     __mutex(const __mutex&);
     125             :     __mutex& operator=(const __mutex&);
     126             : 
     127             :   public:
     128             :     __mutex() 
     129             :     { 
     130             : #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
     131             :       if (__gthread_active_p())
     132             :         __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
     133             : #endif
     134             :     }
     135             : 
     136             : #if __GTHREADS && ! defined __GTHREAD_MUTEX_INIT
     137             :     ~__mutex() 
     138             :     { 
     139             :       if (__gthread_active_p())
     140             :         __gthread_mutex_destroy(&_M_mutex); 
     141             :     }
     142             : #endif 
     143             : 
     144             :     void lock()
     145             :     {
     146             : #if __GTHREADS
     147             :       if (__gthread_active_p())
     148             :         {
     149             :           if (__gthread_mutex_lock(&_M_mutex) != 0)
     150             :             __throw_concurrence_lock_error();
     151             :         }
     152             : #endif
     153             :     }
     154             :     
     155             :     void unlock()
     156             :     {
     157             : #if __GTHREADS
     158             :       if (__gthread_active_p())
     159             :         {
     160             :           if (__gthread_mutex_unlock(&_M_mutex) != 0)
     161             :             __throw_concurrence_unlock_error();
     162             :         }
     163             : #endif
     164             :     }
     165             : 
     166             :     __gthread_mutex_t* gthread_mutex(void)
     167             :       { return &_M_mutex; }
     168             :   };
     169             : 
     170             :   class __recursive_mutex 
     171             :   {
     172             :   private:
     173             : #if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT
     174             :     __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
     175             : #else
     176             :     __gthread_recursive_mutex_t _M_mutex;
     177             : #endif
     178             : 
     179             :     __recursive_mutex(const __recursive_mutex&);
     180             :     __recursive_mutex& operator=(const __recursive_mutex&);
     181             : 
     182             :   public:
     183             :     __recursive_mutex() 
     184             :     { 
     185             : #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
     186             :       if (__gthread_active_p())
     187             :         __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
     188             : #endif
     189             :     }
     190             : 
     191             : #if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
     192             :     ~__recursive_mutex()
     193             :     {
     194             :       if (__gthread_active_p())
     195             :         __gthread_recursive_mutex_destroy(&_M_mutex);
     196             :     }
     197             : #endif
     198             : 
     199             :     void lock()
     200             :     { 
     201             : #if __GTHREADS
     202             :       if (__gthread_active_p())
     203             :         {
     204             :           if (__gthread_recursive_mutex_lock(&_M_mutex) != 0)
     205             :             __throw_concurrence_lock_error();
     206             :         }
     207             : #endif
     208             :     }
     209             :     
     210             :     void unlock()
     211             :     { 
     212             : #if __GTHREADS
     213             :       if (__gthread_active_p())
     214             :         {
     215             :           if (__gthread_recursive_mutex_unlock(&_M_mutex) != 0)
     216             :             __throw_concurrence_unlock_error();
     217             :         }
     218             : #endif
     219             :     }
     220             : 
     221             :     __gthread_recursive_mutex_t* gthread_recursive_mutex(void)
     222             :     { return &_M_mutex; }
     223             :   };
     224             : 
     225             :   /// Scoped lock idiom.
     226             :   // Acquire the mutex here with a constructor call, then release with
     227             :   // the destructor call in accordance with RAII style.
     228             :   class __scoped_lock
     229             :   {
     230             :   public:
     231             :     typedef __mutex __mutex_type;
     232             : 
     233             :   private:
     234             :     __mutex_type& _M_device;
     235             : 
     236             :     __scoped_lock(const __scoped_lock&);
     237             :     __scoped_lock& operator=(const __scoped_lock&);
     238             : 
     239             :   public:
     240             :     explicit __scoped_lock(__mutex_type& __name) : _M_device(__name)
     241             :     { _M_device.lock(); }
     242             : 
     243             :     ~__scoped_lock() throw()
     244             :     { _M_device.unlock(); }
     245             :   };
     246             : 
     247             : #ifdef __GTHREAD_HAS_COND
     248             :   class __cond
     249             :   {
     250             :   private:
     251             : #if __GTHREADS && defined __GTHREAD_COND_INIT
     252             :     __gthread_cond_t _M_cond = __GTHREAD_COND_INIT;
     253             : #else
     254             :     __gthread_cond_t _M_cond;
     255             : #endif
     256             : 
     257             :     __cond(const __cond&);
     258             :     __cond& operator=(const __cond&);
     259             : 
     260             :   public:
     261             :     __cond() 
     262             :     { 
     263             : #if __GTHREADS && ! defined __GTHREAD_COND_INIT
     264             :       if (__gthread_active_p())
     265             :         __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
     266             : #endif
     267             :     }
     268             : 
     269             : #if __GTHREADS && ! defined __GTHREAD_COND_INIT
     270             :     ~__cond() 
     271             :     { 
     272             :       if (__gthread_active_p())
     273             :         __gthread_cond_destroy(&_M_cond); 
     274             :     }
     275             : #endif 
     276             : 
     277             :     void broadcast()
     278             :     {
     279             : #if __GTHREADS
     280             :       if (__gthread_active_p())
     281             :         {
     282             :           if (__gthread_cond_broadcast(&_M_cond) != 0)
     283             :             __throw_concurrence_broadcast_error();
     284             :         }
     285             : #endif
     286             :     }
     287             : 
     288             :     void wait(__mutex *mutex)
     289             :     {
     290             : #if __GTHREADS
     291             :       {
     292             :           if (__gthread_cond_wait(&_M_cond, mutex->gthread_mutex()) != 0)
     293             :             __throw_concurrence_wait_error();
     294             :       }
     295             : #endif
     296             :     }
     297             : 
     298             :     void wait_recursive(__recursive_mutex *mutex)
     299             :     {
     300             : #if __GTHREADS
     301             :       {
     302             :           if (__gthread_cond_wait_recursive(&_M_cond,
     303             :                                             mutex->gthread_recursive_mutex())
     304             :               != 0)
     305             :             __throw_concurrence_wait_error();
     306             :       }
     307             : #endif
     308             :     }
     309             :   };
     310             : #endif
     311             : 
     312             : _GLIBCXX_END_NAMESPACE_VERSION
     313             : } // namespace
     314             : 
     315             : #endif

Generated by: LCOV version 1.14