From f620e1d5c84586f6e60bf5350946ea4a75154ff4 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Sun, 5 Mar 2017 18:38:35 +0000 Subject: [PATCH] Add std::scoped_lock for C++17 * doc/xml/manual/status_cxx2017.xml: Document P0156R2 status. * doc/html/*: Regenerate. * include/std/mutex (scoped_lock): Implement new C++17 template. * testsuite/30_threads/scoped_lock/cons/1.cc: New test. * testsuite/30_threads/scoped_lock/requirements/ explicit_instantiation.cc: New test. * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: New test. From-SVN: r245903 --- libstdc++-v3/ChangeLog | 10 ++ libstdc++-v3/doc/html/manual/debug.html | 2 +- .../doc/html/manual/debug_mode_design.html | 14 +- .../html/manual/documentation_hacking.html | 2 +- libstdc++-v3/doc/html/manual/fstreams.html | 4 +- libstdc++-v3/doc/html/manual/memory.html | 2 +- .../html/manual/policy_data_structures.html | 6 +- .../manual/policy_data_structures_ack.html | 2 +- .../doc/html/manual/profile_mode.html | 2 +- .../doc/html/manual/profile_mode_design.html | 2 +- libstdc++-v3/doc/html/manual/status.html | 8 +- .../doc/xml/manual/status_cxx2017.xml | 9 +- libstdc++-v3/include/std/mutex | 68 +++++++++ .../30_threads/scoped_lock/cons/1.cc | 133 ++++++++++++++++++ .../requirements/explicit_instantiation.cc | 33 +++++ .../scoped_lock/requirements/typedefs.cc | 33 +++++ 16 files changed, 301 insertions(+), 29 deletions(-) create mode 100644 libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc create mode 100644 libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc create mode 100644 libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6a63daf0b7c..ef48d8767cf 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2017-03-05 Jonathan Wakely + + * doc/xml/manual/status_cxx2017.xml: Document P0156R2 status. + * doc/html/*: Regenerate. + * include/std/mutex (scoped_lock): Implement new C++17 template. + * testsuite/30_threads/scoped_lock/cons/1.cc: New test. + * testsuite/30_threads/scoped_lock/requirements/ + explicit_instantiation.cc: New test. + * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: New test. + 2017-03-02 Gerald Pfeifer François Dumont Jonathan Wakely diff --git a/libstdc++-v3/doc/html/manual/debug.html b/libstdc++-v3/doc/html/manual/debug.html index 4f88c0764f8..c0dc2d29b0a 100644 --- a/libstdc++-v3/doc/html/manual/debug.html +++ b/libstdc++-v3/doc/html/manual/debug.html @@ -161,7 +161,7 @@ DRD, Helgrind, and - + ThreadSanitizer (this refers to ThreadSanitizer v1, not the new "tsan" feature built-in to GCC itself).

diff --git a/libstdc++-v3/doc/html/manual/debug_mode_design.html b/libstdc++-v3/doc/html/manual/debug_mode_design.html index 3fcdb2db885..b8d391f185c 100644 --- a/libstdc++-v3/doc/html/manual/debug_mode_design.html +++ b/libstdc++-v3/doc/html/manual/debug_mode_design.html @@ -191,15 +191,11 @@ template<typename _Tp, typename _Allocator = allocator<_Tp> perform, shortening the detect-compile-debug bug hunting cycle and making the debug mode easier to incorporate into development environments by minimizing dependencies.

Achieving link- and run-time coexistence is not a trivial - implementation task. To achieve this goal we required a small - extension to the GNU C++ compiler (since incorporated into the C++11 language specification, described in the GCC Manual for the C++ language as - namespace - association), and a complex organization of debug- and - release-modes. The end result is that we have achieved per-use - recompilation but have had to give up some checking of the - std::basic_string class template (namely, safe - iterators). -

Compile-time coexistence of release- and debug-mode components

Both the release-mode components and the debug-mode + implementation task. To achieve this goal we use inline namespaces and + a complex organization of debug- and release-modes. The end result is + that we have achieved per-use recompilation but have had to give up + some checking of the std::basic_string class template + (namely, safe iterators).

Compile-time coexistence of release- and debug-mode components

Both the release-mode components and the debug-mode components need to exist within a single translation unit so that the debug versions can wrap the release versions. However, only one of these components should be user-visible at any particular diff --git a/libstdc++-v3/doc/html/manual/documentation_hacking.html b/libstdc++-v3/doc/html/manual/documentation_hacking.html index 5cada1a0df4..f3e372603a9 100644 --- a/libstdc++-v3/doc/html/manual/documentation_hacking.html +++ b/libstdc++-v3/doc/html/manual/documentation_hacking.html @@ -114,7 +114,7 @@ ps, and dvi.

Doxygen

Prerequisites

Table B.1. Doxygen Prerequisites

ToolVersionRequired By
coreutils8.5all
bash4.1all
doxygen1.7.6.1all
graphviz2.26graphical hierarchies
pdflatex2007-59pdf output

Prerequisite tools are Bash 2.0 or later, - Doxygen, and + Doxygen, and the GNU coreutils. (GNU versions of find, xargs, and possibly sed and grep are used, just because the GNU versions make diff --git a/libstdc++-v3/doc/html/manual/fstreams.html b/libstdc++-v3/doc/html/manual/fstreams.html index 0b9b30d7532..897057600f9 100644 --- a/libstdc++-v3/doc/html/manual/fstreams.html +++ b/libstdc++-v3/doc/html/manual/fstreams.html @@ -137,8 +137,8 @@

An instructive thread from comp.lang.c++.moderated delved off into this topic starting more or less at - this - post and continuing to the end of the thread. (The subject heading is "binary iostreams" on both comp.std.c++ + this post + and continuing to the end of the thread. (The subject heading is "binary iostreams" on both comp.std.c++ and comp.lang.c++.moderated.) Take special note of the replies by James Kanze and Dietmar Kühl.

Briefly, the problems of byte ordering and type sizes mean that the unformatted functions like ostream::put() and diff --git a/libstdc++-v3/doc/html/manual/memory.html b/libstdc++-v3/doc/html/manual/memory.html index cf58f632b78..d310b695471 100644 --- a/libstdc++-v3/doc/html/manual/memory.html +++ b/libstdc++-v3/doc/html/manual/memory.html @@ -671,7 +671,7 @@ be private. . N2461 .

- + Boost C++ Libraries documentation, shared_ptr . diff --git a/libstdc++-v3/doc/html/manual/policy_data_structures.html b/libstdc++-v3/doc/html/manual/policy_data_structures.html index 0345490f82b..bd0d18e21f5 100644 --- a/libstdc++-v3/doc/html/manual/policy_data_structures.html +++ b/libstdc++-v3/doc/html/manual/policy_data_structures.html @@ -834,7 +834,7 @@ . Generic Programming .

[biblio.dawestimer] - + Boost Timer Library . @@ -844,7 +844,7 @@ . Boost .

[biblio.clearypool] - + Boost Pool Library . @@ -854,7 +854,7 @@ . Boost .

[biblio.maddocktraits] - + Boost Type Traits Library . diff --git a/libstdc++-v3/doc/html/manual/policy_data_structures_ack.html b/libstdc++-v3/doc/html/manual/policy_data_structures_ack.html index 7eb8f15cf38..e450da28cb6 100644 --- a/libstdc++-v3/doc/html/manual/policy_data_structures_ack.html +++ b/libstdc++-v3/doc/html/manual/policy_data_structures_ack.html @@ -18,7 +18,7 @@ reverse iteration can be performed efficiently.

Some test utilities borrow ideas from - boost::timer. + boost::timer.

We would like to thank Scott Meyers for useful comments (without attributing to him any flaws in the design or implementation of the diff --git a/libstdc++-v3/doc/html/manual/profile_mode.html b/libstdc++-v3/doc/html/manual/profile_mode.html index 0c446471185..3f32b30b9f8 100644 --- a/libstdc++-v3/doc/html/manual/profile_mode.html +++ b/libstdc++-v3/doc/html/manual/profile_mode.html @@ -11,7 +11,7 @@ various components at interesting entry/exit points to/from the standard library. Process trace, recognize suboptimal patterns, give advice. For details, see the - Perflint + Perflint paper presented at CGO 2009.

Strengths: diff --git a/libstdc++-v3/doc/html/manual/profile_mode_design.html b/libstdc++-v3/doc/html/manual/profile_mode_design.html index 2d49e338804..8fe9eddba2a 100644 --- a/libstdc++-v3/doc/html/manual/profile_mode_design.html +++ b/libstdc++-v3/doc/html/manual/profile_mode_design.html @@ -60,7 +60,7 @@ call stack of its constructor location.

For details, see - paper presented at + paper presented at CGO 2009.

Analysis and Diagnostics

Final analysis takes place offline, and it is based entirely on the diff --git a/libstdc++-v3/doc/html/manual/status.html b/libstdc++-v3/doc/html/manual/status.html index 842e8d4e61a..0507cc7545a 100644 --- a/libstdc++-v3/doc/html/manual/status.html +++ b/libstdc++-v3/doc/html/manual/status.html @@ -776,11 +776,11 @@ Feature-testing recommendations for C++. N4508 - 6.1 __cpp_lib_shared_mutex >= 201505 Variadic lock_guard - - P0156R0 + 6.1 __cpp_lib_shared_mutex >= 201505 Variadic lock_guard + + P0156R2 - No __cpp_lib_lock_guard_variadic >= 201510


Table 1.6. C++ Technical Specifications Implementation Status

PaperTitleStatusComments
+ 7 __cpp_lib_scoped_lock >= 201703

Table 1.6. C++ Technical Specifications Implementation Status

diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index d6f3899e4f6..6c3f92022be 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -556,6 +556,74 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } +#if __cplusplus > 201402L +#define __cpp_lib_scoped_lock 201703 + /** @brief A scoped lock type for multiple lockable objects. + * + * A scoped_lock controls mutex ownership within a scope, releasing + * ownership in the destructor. + */ + template + class scoped_lock + { + public: + explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...)) + { std::lock(__m...); } + + explicit scoped_lock(_MutexTypes&... __m, adopt_lock_t) noexcept + : _M_devices(std::tie(__m...)) + { } // calling thread owns mutex + + ~scoped_lock() + { + std::apply([](_MutexTypes&... __m) { + char __i[] __attribute__((__unused__)) = { (__m.unlock(), 0)... }; + }, _M_devices); + } + + scoped_lock(const scoped_lock&) = delete; + scoped_lock& operator=(const scoped_lock&) = delete; + + private: + tuple<_MutexTypes&...> _M_devices; + }; + + template<> + class scoped_lock<> + { + public: + explicit scoped_lock() = default; + explicit scoped_lock(adopt_lock_t) noexcept { } + ~scoped_lock() = default; + + scoped_lock(const scoped_lock&) = delete; + scoped_lock& operator=(const scoped_lock&) = delete; + }; + + template + class scoped_lock<_Mutex> + { + public: + using mutex_type = _Mutex; + + explicit scoped_lock(mutex_type& __m) : _M_device(__m) + { _M_device.lock(); } + + explicit scoped_lock(mutex_type& __m, adopt_lock_t) noexcept + : _M_device(__m) + { } // calling thread owns mutex + + ~scoped_lock() + { _M_device.unlock(); } + + scoped_lock(const scoped_lock&) = delete; + scoped_lock& operator=(const scoped_lock&) = delete; + + private: + mutex_type& _M_device; + }; +#endif // C++17 + #ifdef _GLIBCXX_HAS_GTHREADS /// once_flag struct once_flag diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc new file mode 100644 index 00000000000..9f1b48c809a --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/scoped_lock/cons/1.cc @@ -0,0 +1,133 @@ +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++1z } } +// { dg-require-cstdint "" } + +// Copyright (C) 2017 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +#include +#include + +struct BasicLockable +{ + BasicLockable() : locked(false) { } + + ~BasicLockable() noexcept(false) + { + if (locked) + throw 0; + } + + void lock() + { + if (locked) + throw 0; + locked = true; + } + + void unlock() + { + if (!locked) + throw 0; + locked = false; + } + + bool locked; +}; + +template +struct Lockable +{ + BasicLockable m; + void lock() { m.lock(); } + void unlock() { m.unlock(); } + bool try_lock() { if (m.locked) return false; m.lock(); return true; } +}; + +void test01() +{ + BasicLockable m; + + try + { + std::scoped_lock l(m); + VERIFY( m.locked ); + } + catch (...) + { + VERIFY( false ); + } + + VERIFY( !m.locked ); + + m.lock(); + + try + { + std::scoped_lock l(m, std::adopt_lock); + } + catch (...) + { + VERIFY( false ); + } + + VERIFY( !m.locked ); +} + +void test02() +{ + Lockable<1> m1; + Lockable<2> m2; + + try + { + std::scoped_lock, Lockable<2>> l(m1, m2); + VERIFY( m1.m.locked ); + VERIFY( m2.m.locked ); + } + catch (...) + { + VERIFY( false ); + } + + VERIFY( !m1.m.locked ); + VERIFY( !m2.m.locked ); + + m1.lock(); + m2.lock(); + + try + { + std::scoped_lock, Lockable<2>> l(m1, m2, std::adopt_lock); + VERIFY( m1.m.locked ); + VERIFY( m2.m.locked ); + } + catch (...) + { + VERIFY( false ); + } + + VERIFY( !m1.m.locked ); + VERIFY( !m2.m.locked ); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc new file mode 100644 index 00000000000..cbf10757f48 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/explicit_instantiation.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++1z } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2017 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +// NB: This file is for testing with NO OTHER INCLUDES. + +#include + +namespace std +{ + template class scoped_lock<>; + template class scoped_lock; + template class scoped_lock; +} diff --git a/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc new file mode 100644 index 00000000000..55756d87262 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/scoped_lock/requirements/typedefs.cc @@ -0,0 +1,33 @@ +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++1z } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2017 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. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +// NB: This file is for testing with NO OTHER INCLUDES. + +#include + +void test01() +{ + // Check for required typedefs + typedef std::scoped_lock test_type; + typedef test_type::mutex_type mutex_type; +} -- 2.30.2
PaperTitleStatusComments
N4076 diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml index add0514ad9a..1053f2dd84b 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml @@ -719,15 +719,14 @@ Feature-testing recommendations for C++. - Variadic lock_guard - - P0156R0 + + P0156R2 - No - __cpp_lib_lock_guard_variadic >= 201510 + 7 + __cpp_lib_scoped_lock >= 201703