diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-08-14 13:13:37 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-08-14 13:13:37 +0000 |
commit | e96a5306063f19349dd427f0a17cdcd02cf43c48 (patch) | |
tree | de42754637ea28cd22651f0f584d9ed38e54caa3 | |
parent | fbb4fc39f0954ef3581b4526d570677161e5ddeb (diff) |
PR libstdc++/86846 Alternative to pointer-width atomics
Define a class using std::mutex for when std::atomic<memory_resource*>
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<memory_resource*>
using a mutex instead of atomics.
git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@263536 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | libstdc++-v3/ChangeLog | 6 | ||||
-rw-r--r-- | libstdc++-v3/src/c++17/default_resource.h | 11 | ||||
-rw-r--r-- | libstdc++-v3/src/c++17/memory_resource.cc | 41 |
3 files changed, 57 insertions, 1 deletions
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 <jwakely@redhat.com> + 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<memory_resource*> + 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 <memory_resource> #include <atomic> #include <new> +#if ATOMIC_POINTER_LOCK_FREE != 2 +# include <bits/std_mutex.h> // std::mutex, std::lock_guard +# include <bits/move.h> // std::exchange +#endif namespace std _GLIBCXX_VISIBILITY(default) { @@ -81,7 +85,42 @@ namespace pmr constant_init<newdel_res_t> newdel_res{}; constant_init<null_res_t> null_res{}; - constant_init<atomic<memory_resource*>> default_res{&newdel_res.obj}; +#if ATOMIC_POINTER_LOCK_FREE == 2 + using atomic_mem_res = atomic<memory_resource*>; +# 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<mutex> lock(mx); + return val; + } + + memory_resource* exchange(memory_resource* r) + { + lock_guard<mutex> lock(mx); + return std::exchange(val, r); + } + }; +#endif // ATOMIC_POINTER_LOCK_FREE == 2 + +#ifdef _GLIBCXX_ATOMIC_MEM_RES_CAN_BE_CONSTANT_INITIALIZED + constant_init<atomic_mem_res> default_res{&newdel_res.obj}; +#else +# include "default_resource.h" +#endif } // namespace memory_resource* |