]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/bits/std_mutex.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / bits / std_mutex.h
index 67b782544af340f4483b024634ac83aabe99d52b..3a394601868bef49e3f353282087edfe429db42b 100644 (file)
@@ -1,6 +1,6 @@
 // std::mutex implementation -*- C++ -*-
 
-// Copyright (C) 2003-2016 Free Software Foundation, Inc.
+// Copyright (C) 2003-2021 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file bits/mutex.h
+/** @file bits/std_mutex.h
  *  This is an internal header file, included by other library headers.
  *  Do not attempt to use it directly. @headername{mutex}
  */
@@ -39,9 +39,6 @@
 #include <system_error>
 #include <bits/functexcept.h>
 #include <bits/gthr.h>
-#include <bits/move.h> // for std::swap
-
-#ifdef _GLIBCXX_USE_C99_STDINT_TR1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -122,10 +119,80 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
     native_handle_type
-    native_handle()
+    native_handle() noexcept
     { return &_M_mutex; }
   };
 
+  // Implementation details for std::condition_variable
+  class __condvar
+  {
+    using timespec = __gthread_time_t;
+
+  public:
+    __condvar() noexcept
+    {
+#ifndef __GTHREAD_COND_INIT
+      __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
+#endif
+    }
+
+    ~__condvar()
+    {
+      int __e __attribute__((__unused__)) = __gthread_cond_destroy(&_M_cond);
+      __glibcxx_assert(__e != EBUSY); // threads are still blocked
+    }
+
+    __condvar(const __condvar&) = delete;
+    __condvar& operator=(const __condvar&) = delete;
+
+    __gthread_cond_t* native_handle() noexcept { return &_M_cond; }
+
+    // Expects: Calling thread has locked __m.
+    void
+    wait(mutex& __m) noexcept
+    {
+      int __e __attribute__((__unused__))
+       = __gthread_cond_wait(&_M_cond, __m.native_handle());
+      __glibcxx_assert(__e == 0);
+    }
+
+    void
+    wait_until(mutex& __m, timespec& __abs_time) noexcept
+    {
+      __gthread_cond_timedwait(&_M_cond, __m.native_handle(), &__abs_time);
+    }
+
+#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
+    void
+    wait_until(mutex& __m, clockid_t __clock, timespec& __abs_time) noexcept
+    {
+      pthread_cond_clockwait(&_M_cond, __m.native_handle(), __clock,
+                            &__abs_time);
+    }
+#endif
+
+    void
+    notify_one() noexcept
+    {
+      int __e __attribute__((__unused__)) = __gthread_cond_signal(&_M_cond);
+      __glibcxx_assert(__e == 0);
+    }
+
+    void
+    notify_all() noexcept
+    {
+      int __e __attribute__((__unused__)) = __gthread_cond_broadcast(&_M_cond);
+      __glibcxx_assert(__e == 0);
+    }
+
+  protected:
+#ifdef __GTHREAD_COND_INIT
+    __gthread_cond_t _M_cond = __GTHREAD_COND_INIT;
+#else
+    __gthread_cond_t _M_cond;
+#endif
+  };
+
 #endif // _GLIBCXX_HAS_GTHREADS
 
   /// Do not acquire ownership of the mutex.
@@ -139,13 +206,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   struct adopt_lock_t { explicit adopt_lock_t() = default; };
 
   /// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
-  constexpr defer_lock_t       defer_lock { };
+  _GLIBCXX17_INLINE constexpr defer_lock_t     defer_lock { };
 
   /// Tag used to prevent a scoped lock from blocking if a mutex is locked.
-  constexpr try_to_lock_t      try_to_lock { };
+  _GLIBCXX17_INLINE constexpr try_to_lock_t    try_to_lock { };
 
   /// Tag used to make a scoped lock take ownership of a locked mutex.
-  constexpr adopt_lock_t       adopt_lock { };
+  _GLIBCXX17_INLINE constexpr adopt_lock_t     adopt_lock { };
 
   /** @brief A simple scoped lock type.
    *
@@ -161,7 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       explicit lock_guard(mutex_type& __m) : _M_device(__m)
       { _M_device.lock(); }
 
-      lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
+      lock_guard(mutex_type& __m, adopt_lock_t) noexcept : _M_device(__m)
       { } // calling thread owns mutex
 
       ~lock_guard()
@@ -174,200 +241,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       mutex_type&  _M_device;
     };
 
-  /** @brief A movable scoped lock type.
-   *
-   * A unique_lock controls mutex ownership within a scope. Ownership of the
-   * mutex can be delayed until after construction and can be transferred
-   * to another unique_lock by move construction or move assignment. If a
-   * mutex lock is owned when the destructor runs ownership will be released.
-   */
-  template<typename _Mutex>
-    class unique_lock
-    {
-    public:
-      typedef _Mutex mutex_type;
-
-      unique_lock() noexcept
-      : _M_device(0), _M_owns(false)
-      { }
-
-      explicit unique_lock(mutex_type& __m)
-      : _M_device(std::__addressof(__m)), _M_owns(false)
-      {
-       lock();
-       _M_owns = true;
-      }
-
-      unique_lock(mutex_type& __m, defer_lock_t) noexcept
-      : _M_device(std::__addressof(__m)), _M_owns(false)
-      { }
-
-      unique_lock(mutex_type& __m, try_to_lock_t)
-      : _M_device(std::__addressof(__m)), _M_owns(_M_device->try_lock())
-      { }
-
-      unique_lock(mutex_type& __m, adopt_lock_t)
-      : _M_device(std::__addressof(__m)), _M_owns(true)
-      {
-       // XXX calling thread owns mutex
-      }
-
-      template<typename _Clock, typename _Duration>
-       unique_lock(mutex_type& __m,
-                   const chrono::time_point<_Clock, _Duration>& __atime)
-       : _M_device(std::__addressof(__m)),
-         _M_owns(_M_device->try_lock_until(__atime))
-       { }
-
-      template<typename _Rep, typename _Period>
-       unique_lock(mutex_type& __m,
-                   const chrono::duration<_Rep, _Period>& __rtime)
-       : _M_device(std::__addressof(__m)),
-         _M_owns(_M_device->try_lock_for(__rtime))
-       { }
-
-      ~unique_lock()
-      {
-       if (_M_owns)
-         unlock();
-      }
-
-      unique_lock(const unique_lock&) = delete;
-      unique_lock& operator=(const unique_lock&) = delete;
-
-      unique_lock(unique_lock&& __u) noexcept
-      : _M_device(__u._M_device), _M_owns(__u._M_owns)
-      {
-       __u._M_device = 0;
-       __u._M_owns = false;
-      }
-
-      unique_lock& operator=(unique_lock&& __u) noexcept
-      {
-       if(_M_owns)
-         unlock();
-
-       unique_lock(std::move(__u)).swap(*this);
-
-       __u._M_device = 0;
-       __u._M_owns = false;
-
-       return *this;
-      }
-
-      void
-      lock()
-      {
-       if (!_M_device)
-         __throw_system_error(int(errc::operation_not_permitted));
-       else if (_M_owns)
-         __throw_system_error(int(errc::resource_deadlock_would_occur));
-       else
-         {
-           _M_device->lock();
-           _M_owns = true;
-         }
-      }
-
-      bool
-      try_lock()
-      {
-       if (!_M_device)
-         __throw_system_error(int(errc::operation_not_permitted));
-       else if (_M_owns)
-         __throw_system_error(int(errc::resource_deadlock_would_occur));
-       else
-         {
-           _M_owns = _M_device->try_lock();
-           return _M_owns;
-         }
-      }
-
-      template<typename _Clock, typename _Duration>
-       bool
-       try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
-       {
-         if (!_M_device)
-           __throw_system_error(int(errc::operation_not_permitted));
-         else if (_M_owns)
-           __throw_system_error(int(errc::resource_deadlock_would_occur));
-         else
-           {
-             _M_owns = _M_device->try_lock_until(__atime);
-             return _M_owns;
-           }
-       }
-
-      template<typename _Rep, typename _Period>
-       bool
-       try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
-       {
-         if (!_M_device)
-           __throw_system_error(int(errc::operation_not_permitted));
-         else if (_M_owns)
-           __throw_system_error(int(errc::resource_deadlock_would_occur));
-         else
-           {
-             _M_owns = _M_device->try_lock_for(__rtime);
-             return _M_owns;
-           }
-        }
-
-      void
-      unlock()
-      {
-       if (!_M_owns)
-         __throw_system_error(int(errc::operation_not_permitted));
-       else if (_M_device)
-         {
-           _M_device->unlock();
-           _M_owns = false;
-         }
-      }
-
-      void
-      swap(unique_lock& __u) noexcept
-      {
-       std::swap(_M_device, __u._M_device);
-       std::swap(_M_owns, __u._M_owns);
-      }
-
-      mutex_type*
-      release() noexcept
-      {
-       mutex_type* __ret = _M_device;
-       _M_device = 0;
-       _M_owns = false;
-       return __ret;
-      }
-
-      bool
-      owns_lock() const noexcept
-      { return _M_owns; }
-
-      explicit operator bool() const noexcept
-      { return owns_lock(); }
-
-      mutex_type*
-      mutex() const noexcept
-      { return _M_device; }
-
-    private:
-      mutex_type*      _M_device;
-      bool             _M_owns; // XXX use atomic_bool
-    };
-
-  /// Swap overload for unique_lock objects.
-  template<typename _Mutex>
-    inline void
-    swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
-    { __x.swap(__y); }
-
   // @} group mutexes
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
-#endif // _GLIBCXX_USE_C99_STDINT_TR1
-
 #endif // C++11
-
 #endif // _GLIBCXX_MUTEX_H