diff --git a/src/core/internal/traits.d b/src/core/internal/traits.d index 9f4b60a051..0662b457f3 100644 --- a/src/core/internal/traits.d +++ b/src/core/internal/traits.d @@ -240,6 +240,12 @@ template maxAlignment(U...) } } +template classInstanceAlignment(T) +if (is(T == class)) +{ + alias classInstanceAlignment = maxAlignment!(void*, typeof(T.tupleof)); +} + /// See $(REF hasElaborateMove, std,traits) template hasElaborateMove(S) { diff --git a/src/core/thread/osthread.d b/src/core/thread/osthread.d index a4608ff2b4..1470b41e1e 100644 --- a/src/core/thread/osthread.d +++ b/src/core/thread/osthread.d @@ -190,6 +190,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 // @@ -1790,29 +1797,30 @@ package(core.thread): // 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() @nogc { - 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() @nogc { - foreach (ref lock; _locks) - (cast(Mutex)lock.ptr).__dtor(); + (cast(Mutex)_slock.ptr).__dtor(); + (cast(Mutex)_criticalRegionLock.ptr).__dtor(); } __gshared Context* sm_cbeg; @@ -3726,7 +3734,7 @@ private __gshared size_t ll_nThreads; __gshared ll_ThreadData* ll_pThreads; - __gshared align(Mutex.alignof) void[__traits(classInstanceSize, Mutex)] ll_lock; + __gshared align(mutexAlign) void[mutexClassInstanceSize] ll_lock; @property Mutex lowlevelLock() nothrow @nogc {