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)));
                                                       ^

Reply via email to