[PATCH 2/2] ntdll: Handle unaligned SRW locks when using futexes.

Zebediah Figura z.figura12 at gmail.com
Mon Dec 30 12:01:21 CST 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/kernel32/tests/sync.c | 174 ++++++++++++++++++++-----------------
 dlls/ntdll/sync.c          |  74 ++++++++++------
 2 files changed, 141 insertions(+), 107 deletions(-)

diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 477a35287d..dfd98cf102 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -1944,7 +1944,7 @@ static void test_condvars_base(RTL_CONDITION_VARIABLE *cv)
 }
 
 static LONG srwlock_seq = 0;
-static SRWLOCK srwlock_base;
+static SRWLOCK aligned_srwlock;
 static struct
 {
     LONG wrong_execution_order;
@@ -1957,6 +1957,14 @@ static struct
     LONG trylock_shared;
 } srwlock_base_errors;
 
+#include "pshpack1.h"
+struct
+{
+    char c;
+    SRWLOCK lock;
+} unaligned_srwlock;
+#include "poppack.h"
+
 /* Sequence of acquire/release to check boundary conditions:
  *  0: init
  *
@@ -2028,49 +2036,51 @@ static struct
  * 31: end
  */
 
-static DWORD WINAPI srwlock_base_thread1(LPVOID x)
+static DWORD WINAPI srwlock_base_thread1(void *arg)
 {
+    SRWLOCK *lock = arg;
+
     /* seq 2 */
     while (srwlock_seq < 2) Sleep(1);
     Sleep(100);
     if (InterlockedIncrement(&srwlock_seq) != 3)
         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
 
     /* seq 4 */
     while (srwlock_seq < 4) Sleep(1);
     Sleep(100);
     if (InterlockedIncrement(&srwlock_seq) != 5)
         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
 
     /* seq 6 */
     while (srwlock_seq < 6) Sleep(1);
     Sleep(100);
     if (InterlockedIncrement(&srwlock_seq) != 7)
         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
 
     /* seq 8 */
     while (srwlock_seq < 8) Sleep(1);
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (InterlockedIncrement(&srwlock_seq) != 9)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
     Sleep(100);
     if (InterlockedIncrement(&srwlock_seq) != 10)
         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
 
     /* seq 11 */
     while (srwlock_seq < 11) Sleep(1);
-    pAcquireSRWLockShared(&srwlock_base);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 12)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 13 */
     while (srwlock_seq < 13) Sleep(1);
-    pReleaseSRWLockShared(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 14)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
@@ -2079,7 +2089,7 @@ static DWORD WINAPI srwlock_base_thread1(LPVOID x)
     Sleep(50); /* ensure that both the exclusive and shared access thread are queued */
     if (InterlockedIncrement(&srwlock_seq) != 17)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
 
     /* skip over remaining tests if TryAcquireSRWLock* is not available */
     if (!pTryAcquireSRWLockExclusive)
@@ -2087,125 +2097,127 @@ static DWORD WINAPI srwlock_base_thread1(LPVOID x)
 
     /* seq 19 */
     while (srwlock_seq < 19) Sleep(1);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
     {
-        if (pTryAcquireSRWLockShared(&srwlock_base))
+        if (pTryAcquireSRWLockShared(lock))
             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-        if (pTryAcquireSRWLockExclusive(&srwlock_base))
+        if (pTryAcquireSRWLockExclusive(lock))
             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
-        pReleaseSRWLockExclusive(&srwlock_base);
+        pReleaseSRWLockExclusive(lock);
     }
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
 
-    if (pTryAcquireSRWLockShared(&srwlock_base))
+    if (pTryAcquireSRWLockShared(lock))
     {
-        if (pTryAcquireSRWLockShared(&srwlock_base))
-            pReleaseSRWLockShared(&srwlock_base);
+        if (pTryAcquireSRWLockShared(lock))
+            pReleaseSRWLockShared(lock);
         else
             InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-        if (pTryAcquireSRWLockExclusive(&srwlock_base))
+        if (pTryAcquireSRWLockExclusive(lock))
             InterlockedIncrement(&srwlock_base_errors.trylock_excl);
-        pReleaseSRWLockShared(&srwlock_base);
+        pReleaseSRWLockShared(lock);
     }
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
 
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (InterlockedIncrement(&srwlock_seq) != 20)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 21 */
     while (srwlock_seq < 21) Sleep(1);
-    pReleaseSRWLockExclusive(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 22)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 23 */
     while (srwlock_seq < 23) Sleep(1);
-    pReleaseSRWLockShared(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 24)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 25 */
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (srwlock_seq != 25)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
 
-    pAcquireSRWLockShared(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
+    pAcquireSRWLockShared(lock);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 26)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 27 */
     while (srwlock_seq < 27) Sleep(1);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 28)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 29 */
     while (srwlock_seq < 29) Sleep(1);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 30)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     return 0;
 }
 
-static DWORD WINAPI srwlock_base_thread2(LPVOID x)
+static DWORD WINAPI srwlock_base_thread2(void *arg)
 {
+    SRWLOCK *lock = arg;
+
     /* seq 1 */
     while (srwlock_seq < 1) Sleep(1);
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (InterlockedIncrement(&srwlock_seq) != 2)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 3 */
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (srwlock_seq != 3)
         InterlockedIncrement(&srwlock_base_errors.samethread_excl_excl);
-    pReleaseSRWLockExclusive(&srwlock_base);
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
+    pAcquireSRWLockExclusive(lock);
     if (InterlockedIncrement(&srwlock_seq) != 4)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 5 */
-    pAcquireSRWLockShared(&srwlock_base);
+    pAcquireSRWLockShared(lock);
     if (srwlock_seq != 5)
         InterlockedIncrement(&srwlock_base_errors.samethread_excl_shared);
-    pReleaseSRWLockShared(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
+    pAcquireSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 6)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 7 */
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (srwlock_seq != 7)
         InterlockedIncrement(&srwlock_base_errors.samethread_shared_excl);
-    pReleaseSRWLockExclusive(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
-    pAcquireSRWLockShared(&srwlock_base);
-    pReleaseSRWLockShared(&srwlock_base);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
+    pAcquireSRWLockShared(lock);
+    pAcquireSRWLockShared(lock);
+    pReleaseSRWLockShared(lock);
+    pReleaseSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 8)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 9, 10 */
     while (srwlock_seq < 9) Sleep(1);
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (srwlock_seq != 10)
         InterlockedIncrement(&srwlock_base_errors.multithread_excl_excl);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
     if (InterlockedIncrement(&srwlock_seq) != 11)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 12 */
     while (srwlock_seq < 12) Sleep(1);
-    pAcquireSRWLockShared(&srwlock_base);
-    pReleaseSRWLockShared(&srwlock_base);
+    pAcquireSRWLockShared(lock);
+    pReleaseSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 13)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
@@ -2215,12 +2227,12 @@ static DWORD WINAPI srwlock_base_thread2(LPVOID x)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 17 */
-    pAcquireSRWLockExclusive(&srwlock_base);
+    pAcquireSRWLockExclusive(lock);
     if (srwlock_seq != 17)
         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
     if (InterlockedIncrement(&srwlock_seq) != 18)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
-    pReleaseSRWLockExclusive(&srwlock_base);
+    pReleaseSRWLockExclusive(lock);
 
     /* skip over remaining tests if TryAcquireSRWLock* is not available */
     if (!pTryAcquireSRWLockExclusive)
@@ -2228,20 +2240,20 @@ static DWORD WINAPI srwlock_base_thread2(LPVOID x)
 
     /* seq 20 */
     while (srwlock_seq < 20) Sleep(1);
-    if (pTryAcquireSRWLockShared(&srwlock_base))
+    if (pTryAcquireSRWLockShared(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 21)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 22 */
     while (srwlock_seq < 22) Sleep(1);
-    if (pTryAcquireSRWLockShared(&srwlock_base))
-        pReleaseSRWLockShared(&srwlock_base);
+    if (pTryAcquireSRWLockShared(lock))
+        pReleaseSRWLockShared(lock);
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 23)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
@@ -2249,47 +2261,47 @@ static DWORD WINAPI srwlock_base_thread2(LPVOID x)
     /* seq 24 */
     while (srwlock_seq < 24) Sleep(1);
     Sleep(50); /* ensure that exclusive access request is queued */
-    if (pTryAcquireSRWLockShared(&srwlock_base))
+    if (pTryAcquireSRWLockShared(lock))
     {
-        pReleaseSRWLockShared(&srwlock_base);
+        pReleaseSRWLockShared(lock);
         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
     }
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 25)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
 
     /* seq 26 */
     while (srwlock_seq < 26) Sleep(1);
-    if (pTryAcquireSRWLockShared(&srwlock_base))
-        pReleaseSRWLockShared(&srwlock_base);
+    if (pTryAcquireSRWLockShared(lock))
+        pReleaseSRWLockShared(lock);
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 27)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 28 */
     while (srwlock_seq < 28) Sleep(1);
-    if (pTryAcquireSRWLockShared(&srwlock_base))
-        pReleaseSRWLockShared(&srwlock_base);
+    if (pTryAcquireSRWLockShared(lock))
+        pReleaseSRWLockShared(lock);
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
+    if (pTryAcquireSRWLockExclusive(lock))
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 29)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 30 */
     while (srwlock_seq < 30) Sleep(1);
-    if (pTryAcquireSRWLockShared(&srwlock_base))
-        pReleaseSRWLockShared(&srwlock_base);
+    if (pTryAcquireSRWLockShared(lock))
+        pReleaseSRWLockShared(lock);
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_shared);
-    if (pTryAcquireSRWLockExclusive(&srwlock_base))
-        pReleaseSRWLockExclusive(&srwlock_base);
+    if (pTryAcquireSRWLockExclusive(lock))
+        pReleaseSRWLockExclusive(lock);
     else
         InterlockedIncrement(&srwlock_base_errors.trylock_excl);
     if (InterlockedIncrement(&srwlock_seq) != 31)
@@ -2298,8 +2310,10 @@ static DWORD WINAPI srwlock_base_thread2(LPVOID x)
     return 0;
 }
 
-static DWORD WINAPI srwlock_base_thread3(LPVOID x)
+static DWORD WINAPI srwlock_base_thread3(void *arg)
 {
+    SRWLOCK *lock = arg;
+
     /* seq 15 */
     while (srwlock_seq < 15) Sleep(1);
     Sleep(50); /* some delay, so that thread2 can try to acquire a second exclusive lock */
@@ -2307,10 +2321,10 @@ static DWORD WINAPI srwlock_base_thread3(LPVOID x)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
     /* seq 18 */
-    pAcquireSRWLockShared(&srwlock_base);
+    pAcquireSRWLockShared(lock);
     if (srwlock_seq != 18)
         InterlockedIncrement(&srwlock_base_errors.excl_not_preferred);
-    pReleaseSRWLockShared(&srwlock_base);
+    pReleaseSRWLockShared(lock);
     if (InterlockedIncrement(&srwlock_seq) != 19)
         InterlockedIncrement(&srwlock_base_errors.wrong_execution_order);
 
@@ -2326,7 +2340,7 @@ static DWORD WINAPI srwlock_base_thread3(LPVOID x)
     return 0;
 }
 
-static void test_srwlock_base(void)
+static void test_srwlock_base(SRWLOCK *lock)
 {
     HANDLE h1, h2, h3;
     DWORD dummy;
@@ -2338,12 +2352,13 @@ static void test_srwlock_base(void)
         return;
     }
 
-    pInitializeSRWLock(&srwlock_base);
+    pInitializeSRWLock(lock);
     memset(&srwlock_base_errors, 0, sizeof(srwlock_base_errors));
+    srwlock_seq = 0;
 
-    h1 = CreateThread(NULL, 0, srwlock_base_thread1, NULL, 0, &dummy);
-    h2 = CreateThread(NULL, 0, srwlock_base_thread2, NULL, 0, &dummy);
-    h3 = CreateThread(NULL, 0, srwlock_base_thread3, NULL, 0, &dummy);
+    h1 = CreateThread(NULL, 0, srwlock_base_thread1, lock, 0, &dummy);
+    h2 = CreateThread(NULL, 0, srwlock_base_thread2, lock, 0, &dummy);
+    h3 = CreateThread(NULL, 0, srwlock_base_thread3, lock, 0, &dummy);
 
     srwlock_seq = 1; /* go */
     while (srwlock_seq < 31)
@@ -2744,7 +2759,8 @@ START_TEST(sync)
     test_condvars_base(&aligned_cv);
     test_condvars_base(&unaligned_cv.cv);
     test_condvars_consumer_producer();
-    test_srwlock_base();
+    test_srwlock_base(&aligned_srwlock);
+    test_srwlock_base(&unaligned_srwlock.lock);
     test_srwlock_example();
     test_alertable_wait();
     test_apc_deadlock();
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index 302b4cc7e0..1bc002608a 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -1698,14 +1698,17 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu
 
 static NTSTATUS fast_try_acquire_srw_exclusive( RTL_SRWLOCK *lock )
 {
-    int old, new;
+    int old, new, *futex;
     NTSTATUS ret;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     do
     {
-        old = *(int *)lock;
+        old = *futex;
 
         if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)
                 && !(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK))
@@ -1719,31 +1722,34 @@ static NTSTATUS fast_try_acquire_srw_exclusive( RTL_SRWLOCK *lock )
             new = old;
             ret = STATUS_TIMEOUT;
         }
-    } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+    } while (interlocked_cmpxchg( futex, new, old ) != old);
 
     return ret;
 }
 
 static NTSTATUS fast_acquire_srw_exclusive( RTL_SRWLOCK *lock )
 {
-    int old, new;
+    int old, new, *futex;
     BOOLEAN wait;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     /* Atomically increment the exclusive waiter count. */
     do
     {
-        old = *(int *)lock;
+        old = *futex;
         new = old + SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_INC;
         assert(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK);
-    } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+    } while (interlocked_cmpxchg( futex, new, old ) != old);
 
     for (;;)
     {
         do
         {
-            old = *(int *)lock;
+            old = *futex;
 
             if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)
                     && !(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK))
@@ -1759,12 +1765,12 @@ static NTSTATUS fast_acquire_srw_exclusive( RTL_SRWLOCK *lock )
                 new = old;
                 wait = TRUE;
             }
-        } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+        } while (interlocked_cmpxchg( futex, new, old ) != old);
 
         if (!wait)
             return STATUS_SUCCESS;
 
-        futex_wait_bitset( (int *)lock, new, NULL, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
+        futex_wait_bitset( futex, new, NULL, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
     }
 
     return STATUS_SUCCESS;
@@ -1772,14 +1778,17 @@ static NTSTATUS fast_acquire_srw_exclusive( RTL_SRWLOCK *lock )
 
 static NTSTATUS fast_try_acquire_srw_shared( RTL_SRWLOCK *lock )
 {
-    int new, old;
+    int new, old, *futex;
     NTSTATUS ret;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     do
     {
-        old = *(int *)lock;
+        old = *futex;
 
         if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)
                 && !(old & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
@@ -1795,23 +1804,26 @@ static NTSTATUS fast_try_acquire_srw_shared( RTL_SRWLOCK *lock )
             new = old;
             ret = STATUS_TIMEOUT;
         }
-    } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+    } while (interlocked_cmpxchg( futex, new, old ) != old);
 
     return ret;
 }
 
 static NTSTATUS fast_acquire_srw_shared( RTL_SRWLOCK *lock )
 {
-    int old, new;
+    int old, new, *futex;
     BOOLEAN wait;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     for (;;)
     {
         do
         {
-            old = *(int *)lock;
+            old = *futex;
 
             if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)
                     && !(old & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
@@ -1827,12 +1839,12 @@ static NTSTATUS fast_acquire_srw_shared( RTL_SRWLOCK *lock )
                 new = old | SRWLOCK_FUTEX_SHARED_WAITERS_BIT;
                 wait = TRUE;
             }
-        } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+        } while (interlocked_cmpxchg( futex, new, old ) != old);
 
         if (!wait)
             return STATUS_SUCCESS;
 
-        futex_wait_bitset( (int *)lock, new, NULL, SRWLOCK_FUTEX_BITSET_SHARED );
+        futex_wait_bitset( futex, new, NULL, SRWLOCK_FUTEX_BITSET_SHARED );
     }
 
     return STATUS_SUCCESS;
@@ -1840,17 +1852,20 @@ static NTSTATUS fast_acquire_srw_shared( RTL_SRWLOCK *lock )
 
 static NTSTATUS fast_release_srw_exclusive( RTL_SRWLOCK *lock )
 {
-    int old, new;
+    int old, new, *futex;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     do
     {
-        old = *(int *)lock;
+        old = *futex;
 
         if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT))
         {
-            ERR("Lock %p is not owned exclusive! (%#x)\n", lock, *(int *)lock);
+            ERR("Lock %p is not owned exclusive! (%#x)\n", lock, *futex);
             return STATUS_RESOURCE_NOT_OWNED;
         }
 
@@ -1858,43 +1873,46 @@ static NTSTATUS fast_release_srw_exclusive( RTL_SRWLOCK *lock )
 
         if (!(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
             new &= ~SRWLOCK_FUTEX_SHARED_WAITERS_BIT;
-    } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+    } while (interlocked_cmpxchg( futex, new, old ) != old);
 
     if (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)
-        futex_wake_bitset( (int *)lock, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
+        futex_wake_bitset( futex, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
     else if (old & SRWLOCK_FUTEX_SHARED_WAITERS_BIT)
-        futex_wake_bitset( (int *)lock, INT_MAX, SRWLOCK_FUTEX_BITSET_SHARED );
+        futex_wake_bitset( futex, INT_MAX, SRWLOCK_FUTEX_BITSET_SHARED );
 
     return STATUS_SUCCESS;
 }
 
 static NTSTATUS fast_release_srw_shared( RTL_SRWLOCK *lock )
 {
-    int old, new;
+    int old, new, *futex;
 
     if (!use_futexes()) return STATUS_NOT_IMPLEMENTED;
 
+    if (!(futex = get_futex( &lock->Ptr )))
+        return STATUS_NOT_IMPLEMENTED;
+
     do
     {
-        old = *(int *)lock;
+        old = *futex;
 
         if (old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)
         {
-            ERR("Lock %p is owned exclusive! (%#x)\n", lock, *(int *)lock);
+            ERR("Lock %p is owned exclusive! (%#x)\n", lock, *futex);
             return STATUS_RESOURCE_NOT_OWNED;
         }
         else if (!(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK))
         {
-            ERR("Lock %p is not owned shared! (%#x)\n", lock, *(int *)lock);
+            ERR("Lock %p is not owned shared! (%#x)\n", lock, *futex);
             return STATUS_RESOURCE_NOT_OWNED;
         }
 
         new = old - SRWLOCK_FUTEX_SHARED_OWNERS_INC;
-    } while (interlocked_cmpxchg( (int *)lock, new, old ) != old);
+    } while (interlocked_cmpxchg( futex, new, old ) != old);
 
     /* Optimization: only bother waking if there are actually exclusive waiters. */
     if (!(new & SRWLOCK_FUTEX_SHARED_OWNERS_MASK) && (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK))
-        futex_wake_bitset( (int *)lock, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
+        futex_wake_bitset( futex, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE );
 
     return STATUS_SUCCESS;
 }
-- 
2.24.1




More information about the wine-devel mailing list