From: Jonathan Wakely Date: Wed, 25 Jul 2018 10:40:12 +0000 (+0100) Subject: Move std::unique_lock definition to a separate header X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1fba0606b813ab0925e7fc9ee92c9b57c7c3b94f;p=gcc.git Move std::unique_lock definition to a separate header This will allow std::mutex and std::lock_guard to be used elsewhere in the library without pulling in the whole of . Previously the whole of was conditional on the _GLIBCXX_USE_C99_STDINT_TR1 macro, but only the std::unique_lock members that use facilities should depend on that. std::mutex only needs to depend on _GLIBCXX_HAS_GTHREADS and std::lock_guard can be defined unconditionally. Some parts of and are based on code in which dates from 2003. However, the std::unique_lock implementation was added in 2008 by r135007, without using any earlier code. Therefore the new header file has copyright years 2008-2018. * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/std_mutex.h [!_GLIBCXX_USE_C99_STDINT_TR1] (mutex) (lock_guard): Define independent of _GLIBCXX_USE_C99_STDINT_TR1. (unique_lock): Move definition to ... * include/bits/unique_lock.h: New header. [!_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock): Define unconditionally. [_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock(mutex_type&, time_point)) (unique_lock(mutex_type&, duration), unique_lock::try_lock_until) (unique_lock::try_lock_for): Define only when is usable. * include/std/condition_variable: Include . * include/std/mutex: Likewise. From-SVN: r262963 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index bef5a97cd6e..76903e3e9ab 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2018-07-25 Jonathan Wakely + + * include/Makefile.am: Add new header. + * include/Makefile.in: Regenerate. + * include/bits/std_mutex.h [!_GLIBCXX_USE_C99_STDINT_TR1] (mutex) + (lock_guard): Define independent of _GLIBCXX_USE_C99_STDINT_TR1. + (unique_lock): Move definition to ... + * include/bits/unique_lock.h: New header. + [!_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock): Define unconditionally. + [_GLIBCXX_USE_C99_STDINT_TR1] (unique_lock(mutex_type&, time_point)) + (unique_lock(mutex_type&, duration), unique_lock::try_lock_until) + (unique_lock::try_lock_for): Define only when is usable. + * include/std/condition_variable: Include . + * include/std/mutex: Likewise. + 2018-07-24 Jonathan Wakely * config/abi/pre/gnu.ver: Export new symbols. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 9daa8856e70..70db3cb6260 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -199,6 +199,7 @@ bits_headers = \ ${bits_srcdir}/stringfwd.h \ ${bits_srcdir}/string_view.tcc \ ${bits_srcdir}/uniform_int_dist.h \ + ${bits_srcdir}/unique_lock.h \ ${bits_srcdir}/unique_ptr.h \ ${bits_srcdir}/unordered_map.h \ ${bits_srcdir}/unordered_set.h \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index a122c9cfe2c..0e1cbe489d7 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -492,6 +492,7 @@ bits_headers = \ ${bits_srcdir}/stringfwd.h \ ${bits_srcdir}/string_view.tcc \ ${bits_srcdir}/uniform_int_dist.h \ + ${bits_srcdir}/unique_lock.h \ ${bits_srcdir}/unique_ptr.h \ ${bits_srcdir}/unordered_map.h \ ${bits_srcdir}/unordered_set.h \ diff --git a/libstdc++-v3/include/bits/std_mutex.h b/libstdc++-v3/include/bits/std_mutex.h index 34d22907a06..41a9b30636a 100644 --- a/libstdc++-v3/include/bits/std_mutex.h +++ b/libstdc++-v3/include/bits/std_mutex.h @@ -39,9 +39,6 @@ #include #include #include -#include // for std::swap - -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 namespace std _GLIBCXX_VISIBILITY(default) { @@ -174,200 +171,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 - 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) noexcept - : _M_device(std::__addressof(__m)), _M_owns(true) - { - // XXX calling thread owns mutex - } - - template - 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 - 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 - 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 - 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 - 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 diff --git a/libstdc++-v3/include/bits/unique_lock.h b/libstdc++-v3/include/bits/unique_lock.h new file mode 100644 index 00000000000..e0e7400b516 --- /dev/null +++ b/libstdc++-v3/include/bits/unique_lock.h @@ -0,0 +1,249 @@ +// std::unique_lock implementation -*- C++ -*- + +// Copyright (C) 2008-2018 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 +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file bits/unique_lock.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{mutex} + */ + +#ifndef _GLIBCXX_UNIQUE_LOCK_H +#define _GLIBCXX_UNIQUE_LOCK_H 1 + +#pragma GCC system_header + +#if __cplusplus < 201103L +# include +#else + +#include +#include // for std::swap + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + /** + * @ingroup mutexes + * @{ + */ + + /** @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 + 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) noexcept + : _M_device(std::__addressof(__m)), _M_owns(true) + { + // XXX calling thread owns mutex + } + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template + 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 + unique_lock(mutex_type& __m, + const chrono::duration<_Rep, _Period>& __rtime) + : _M_device(std::__addressof(__m)), + _M_owns(_M_device->try_lock_for(__rtime)) + { } +#endif + + ~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; + } + } + +#ifdef _GLIBCXX_USE_C99_STDINT_TR1 + template + 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 + 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; + } + } +#endif + + 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; + }; + + /// Swap overload for unique_lock objects. + template + inline void + swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept + { __x.swap(__y); } + + // @} group mutexes +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace + +#endif // C++11 +#endif // _GLIBCXX_UNIQUE_LOCK_H diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index 84863a162d6..88ab775f771 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -37,6 +37,7 @@ #include #include +#include #include #include #include diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index 71e915cc5a0..9318a8d1a5d 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -41,6 +41,7 @@ #include #include #include +#include #if ! _GTHREAD_USE_MUTEX_TIMEDLOCK # include # include