[PR,d/88462] Committed fix for abort in pthread_mutex_init on Solaris

Message ID CABOHX+dWvrhYOgLUhoimvMNDk52ETkCd3KFK+Z6rAZ7QVkCiRQ@mail.gmail.com
State New
Headers show
Series
  • [PR,d/88462] Committed fix for abort in pthread_mutex_init on Solaris
Related show

Commit Message

Iain Buclaw April 1, 2019, 2:44 p.m.
Hi,

This patch merges the libphobos druntime library with druntime
upstream d57fa1ff.

Fixes alignment of internal core.thread locks that were found to be
the cause of abort() being called inside pthread_mutex_init(), fixing
the second part of PR d/88462.

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk as r270057.

-- 
Iain
---

Patch

diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index ed756fa6c18..15a55ab612a 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@ 
-b9564bef1147c797842e6c1a804f2c3565c64ac1
+d57fa1ffaecc858229ed7a730e8486b59197dee5
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/core/internal/traits.d b/libphobos/libdruntime/core/internal/traits.d
index d5786808054..e56f016c355 100644
--- a/libphobos/libdruntime/core/internal/traits.d
+++ b/libphobos/libdruntime/core/internal/traits.d
@@ -170,6 +170,29 @@  template anySatisfy(alias F, T...)
     }
 }
 
+// simplified from std.traits.maxAlignment
+template maxAlignment(U...)
+{
+    static if (U.length == 0)
+        static assert(0);
+    else static if (U.length == 1)
+        enum maxAlignment = U[0].alignof;
+    else static if (U.length == 2)
+        enum maxAlignment = U[0].alignof > U[1].alignof ? U[0].alignof : U[1].alignof;
+    else
+    {
+        enum a = maxAlignment!(U[0 .. ($+1)/2]);
+        enum b = maxAlignment!(U[($+1)/2 .. $]);
+        enum maxAlignment = a > b ? a : b;
+    }
+}
+
+template classInstanceAlignment(T)
+if (is(T == class))
+{
+    alias classInstanceAlignment = maxAlignment!(void*, typeof(T.tupleof));
+}
+
 // Somehow fails for non-static nested structs without support for aliases
 template hasElaborateDestructor(T...)
 {
diff --git a/libphobos/libdruntime/core/thread.d b/libphobos/libdruntime/core/thread.d
index e502072be7a..1cf26641e05 100644
--- a/libphobos/libdruntime/core/thread.d
+++ b/libphobos/libdruntime/core/thread.d
@@ -114,6 +114,13 @@  private
 {
     import core.atomic, core.memory, core.sync.mutex;
 
+    // Handling unaligned mutexes are not supported on all platforms, so we must
+    // ensure that the address of all shared data are appropriately aligned.
+    import core.internal.traits : classInstanceAlignment;
+
+    enum mutexAlign = classInstanceAlignment!Mutex;
+    enum mutexClassInstanceSize = __traits(classInstanceSize, Mutex);
+
     //
     // exposed by compiler runtime
     //
@@ -1708,29 +1715,30 @@  private:
     // lock order inversion.
     @property static Mutex slock() nothrow @nogc
     {
-        return cast(Mutex)_locks[0].ptr;
+        return cast(Mutex)_slock.ptr;
     }
 
     @property static Mutex criticalRegionLock() nothrow @nogc
     {
-        return cast(Mutex)_locks[1].ptr;
+        return cast(Mutex)_criticalRegionLock.ptr;
     }
 
-    __gshared align(Mutex.alignof) void[__traits(classInstanceSize, Mutex)][2] _locks;
+    __gshared align(mutexAlign) void[mutexClassInstanceSize] _slock;
+    __gshared align(mutexAlign) void[mutexClassInstanceSize] _criticalRegionLock;
 
     static void initLocks()
     {
-        foreach (ref lock; _locks)
-        {
-            lock[] = typeid(Mutex).initializer[];
-            (cast(Mutex)lock.ptr).__ctor();
-        }
+        _slock[] = typeid(Mutex).initializer[];
+        (cast(Mutex)_slock.ptr).__ctor();
+
+        _criticalRegionLock[] = typeid(Mutex).initializer[];
+        (cast(Mutex)_criticalRegionLock.ptr).__ctor();
     }
 
     static void termLocks()
     {
-        foreach (ref lock; _locks)
-            (cast(Mutex)lock.ptr).__dtor();
+        (cast(Mutex)_slock.ptr).__dtor();
+        (cast(Mutex)_criticalRegionLock.ptr).__dtor();
     }
 
     __gshared Context*  sm_cbeg;