re PR d/88462 (All D execution tests FAIL on Solaris/SPARC)
authorIain Buclaw <ibuclaw@gcc.gnu.org>
Mon, 1 Apr 2019 14:44:04 +0000 (14:44 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Mon, 1 Apr 2019 14:44:04 +0000 (14:44 +0000)
    PR d/88462
libphobos: Fix abort in pthread_mutex_init on Solaris.

Merges upstream druntime d57fa1ff.

Reviewed-on: https://github.com/dlang/druntime/pull/2534

From-SVN: r270057

libphobos/libdruntime/MERGE
libphobos/libdruntime/core/internal/traits.d
libphobos/libdruntime/core/thread.d

index ed756fa6c1855d29853d56365c720a3de4da9684..15a55ab612a56f7a2538c73341f5c3e9081398fa 100644 (file)
@@ -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.
index d57868080541dae2289fac810bd7d87910e8edad..e56f016c35596c079250730d4cbf037e0c780db6 100644 (file)
@@ -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...)
 {
index e502072be7a7f2e2185d157318cc16fcc2297b78..1cf26641e05e34b411993042b79850511dec04a2 100644 (file)
@@ -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;