summaryrefslogtreecommitdiff
path: root/libphobos/libdruntime
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gcc.gnu.org>2019-04-01 14:44:04 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2019-04-01 14:44:04 +0000
commitca0f5734fe3daccfbd630628e4c11ebec230220d (patch)
tree628b32f528e89d8a7c5d36688a8974b03acf7907 /libphobos/libdruntime
parentf1ba6c5a51936ac9065789b1fdb77f4e35f90efd (diff)
re PR d/88462 (All D execution tests FAIL on Solaris/SPARC)
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
Diffstat (limited to 'libphobos/libdruntime')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/traits.d23
-rw-r--r--libphobos/libdruntime/core/thread.d28
3 files changed, 42 insertions, 11 deletions
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;