https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86846
--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> --- Ah, that patch assumes this is defined: #ifdef __GTHREAD_MUTEX_INIT __native_type _M_mutex = __GTHREAD_MUTEX_INIT; constexpr __mutex_base() noexcept = default; i.e. PTHREAD_MUTEX_INITIALIZER. If that's not available we might just need to use a global mutex, without the constant_init<> wrapper that makes the object immortal. In that case it will be risky to use the default memory resource functions after static destructors start (which is bad practice anyway). So this would be a bit more robust: --- 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,39 @@ namespace pmr constant_init<newdel_res_t> newdel_res{}; constant_init<null_res_t> null_res{}; +#if ATOMIC_POINTER_LOCK_FREE == 2 constant_init<atomic<memory_resource*>> default_res{&newdel_res.obj}; +#else + struct locking_atomic + { +#ifdef __GTHREAD_MUTEX_INIT + // std::mutex has constexpr constructor + constexpr +#endif + locking_atomic(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); + } + }; +#ifdef __GTHREAD_MUTEX_INIT + constant_init<locking_atomic> default_res{&newdel_res.obj}; +#else + struct { + locking_atomic obj = &newdel_res.obj; + } default_res __attribute__ ((init_priority (100))); +#endif +#endif } // namespace memory_resource* Unfortunately this produces a warning for targets without pointer-width atomics and without PTHREAD_MUTEX_INITIALIZER: /home/jwakely/src/gcc/gcc/libstdc++-v3/src/c++17/memory_resource.cc:119:55: warning: requested init_priority is reserved for internal use } default_res __attribute__ ((init_priority (100))); ^