From 26e130482e69aef0dbd0bc4c218a82ba7b64bce7 Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Tue, 14 Aug 2018 14:13:37 +0100 Subject: [PATCH] PR libstdc++/86846 Alternative to pointer-width atomics Define a class using std::mutex for when std::atomic cannot be used to implement the default memory resource. When std::mutex constructor is not constexpr the constant_init trick won't work, so just define a global and use init_priority for it. The compiler warns about using reserved priority, so put the definition in a header file using #pragma GCC system_header to suppress the warning. PR libstdc++/86846 * src/c++17/default_resource.h: New file, defining default_res. * src/c++17/memory_resource.cc [ATOMIC_POINTER_LOCK_FREE != 2] (atomic_mem_res): Define alternative for atomic using a mutex instead of atomics. From-SVN: r263536 --- libstdc++-v3/ChangeLog | 6 ++++ libstdc++-v3/src/c++17/default_resource.h | 11 ++++++ libstdc++-v3/src/c++17/memory_resource.cc | 41 ++++++++++++++++++++++- 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 libstdc++-v3/src/c++17/default_resource.h diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 55570c77bf2..15ff3db6134 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,11 @@ 2018-08-14 Jonathan Wakely + PR libstdc++/86846 + * src/c++17/default_resource.h: New file, defining default_res. + * src/c++17/memory_resource.cc [ATOMIC_POINTER_LOCK_FREE != 2] + (atomic_mem_res): Define alternative for atomic + using a mutex instead of atomics. + PR libstdc++/85343 * config/abi/pre/gnu.ver: Export new symbol. * doc/xml/manual/abi.xml: Document new versions. diff --git a/libstdc++-v3/src/c++17/default_resource.h b/libstdc++-v3/src/c++17/default_resource.h new file mode 100644 index 00000000000..522cee13b90 --- /dev/null +++ b/libstdc++-v3/src/c++17/default_resource.h @@ -0,0 +1,11 @@ +// This is only in a header so we can use the system_header pragma, +// to suppress the warning caused by using a reserved init_priority. +#pragma GCC system_header + +#if ATOMIC_POINTER_LOCK_FREE == 2 || defined(__GTHREAD_MUTEX_INIT) +# error "This file should not be included for this build" +#endif + +struct { + atomic_mem_res obj = &newdel_res.obj; +} default_res __attribute__ ((init_priority (100))); diff --git a/libstdc++-v3/src/c++17/memory_resource.cc b/libstdc++-v3/src/c++17/memory_resource.cc index c3ae2b69f71..bd8f32d931e 100644 --- a/libstdc++-v3/src/c++17/memory_resource.cc +++ b/libstdc++-v3/src/c++17/memory_resource.cc @@ -25,6 +25,10 @@ #include #include #include +#if ATOMIC_POINTER_LOCK_FREE != 2 +# include // std::mutex, std::lock_guard +# include // std::exchange +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -81,7 +85,42 @@ namespace pmr constant_init newdel_res{}; constant_init null_res{}; - constant_init> default_res{&newdel_res.obj}; +#if ATOMIC_POINTER_LOCK_FREE == 2 + using atomic_mem_res = atomic; +# define _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED +#else + // Can't use pointer-width atomics, define a type using a mutex instead: + struct atomic_mem_res + { +# ifdef __GTHREAD_MUTEX_INIT +# define _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED + // std::mutex has constexpr constructor + constexpr +# endif + atomic_mem_res(memory_resource* r) : val(r) { } + + mutex mx; + memory_resource* val; + + memory_resource* load() + { + lock_guard lock(mx); + return val; + } + + memory_resource* exchange(memory_resource* r) + { + lock_guard lock(mx); + return std::exchange(val, r); + } + }; +#endif // ATOMIC_POINTER_LOCK_FREE == 2 + +#ifdef _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED + constant_init default_res{&newdel_res.obj}; +#else +# include "default_resource.h" +#endif } // namespace memory_resource* -- 2.30.2