diff options
Diffstat (limited to 'libstdc++-v3')
-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 55570c7..15ff3db 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 0000000..522cee1 --- /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 c3ae2b69..bd8f32d 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* |