[PATCH 1/2] ntdll: Handle unaligned condition variables when using futexes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48389 Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> --- dlls/kernel32/tests/sync.c | 76 ++++++++++++++++----------- dlls/ntdll/sync.c | 105 ++++++++++++++++++++++++++++++------- 2 files changed, 132 insertions(+), 49 deletions(-) diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c index 40cad1c4c5..477a35287d 100644 --- a/dlls/kernel32/tests/sync.c +++ b/dlls/kernel32/tests/sync.c @@ -1718,10 +1718,18 @@ static void test_condvars_consumer_producer(void) /* Sample test for some sequence of events happening, sequenced using "condvar_seq" */ static DWORD condvar_seq = 0; -static CONDITION_VARIABLE condvar_base = CONDITION_VARIABLE_INIT; +static CONDITION_VARIABLE aligned_cv; static CRITICAL_SECTION condvar_crit; static SRWLOCK condvar_srwlock; +#include "pshpack1.h" +static struct +{ + char c; + CONDITION_VARIABLE cv; +} unaligned_cv; +#include "poppack.h" + /* Sequence of wake/sleep to check boundary conditions: * 0: init * 1: producer emits a WakeConditionVariable without consumer waiting. @@ -1741,28 +1749,31 @@ static SRWLOCK condvar_srwlock; * 12: producer (shared) wakes up consumer (shared) * 13: end */ -static DWORD WINAPI condvar_base_producer(LPVOID x) { +static DWORD WINAPI condvar_base_producer(void *arg) +{ + CONDITION_VARIABLE *cv = arg; + while (condvar_seq < 1) Sleep(1); - pWakeConditionVariable (&condvar_base); + pWakeConditionVariable(cv); condvar_seq = 2; while (condvar_seq < 3) Sleep(1); - pWakeAllConditionVariable (&condvar_base); + pWakeAllConditionVariable(cv); condvar_seq = 4; while (condvar_seq < 5) Sleep(1); EnterCriticalSection (&condvar_crit); - pWakeConditionVariable (&condvar_base); + pWakeConditionVariable(cv); LeaveCriticalSection (&condvar_crit); while (condvar_seq < 6) Sleep(1); EnterCriticalSection (&condvar_crit); - pWakeAllConditionVariable (&condvar_base); + pWakeAllConditionVariable(cv); LeaveCriticalSection (&condvar_crit); while (condvar_seq < 8) Sleep(1); EnterCriticalSection (&condvar_crit); - pWakeConditionVariable (&condvar_base); + pWakeConditionVariable(cv); Sleep(50); LeaveCriticalSection (&condvar_crit); @@ -1772,36 +1783,38 @@ static DWORD WINAPI condvar_base_producer(LPVOID x) { while (condvar_seq < 9) Sleep(1); pAcquireSRWLockExclusive(&condvar_srwlock); - pWakeConditionVariable(&condvar_base); + pWakeConditionVariable(cv); pReleaseSRWLockExclusive(&condvar_srwlock); while (condvar_seq < 10) Sleep(1); pAcquireSRWLockExclusive(&condvar_srwlock); - pWakeConditionVariable(&condvar_base); + pWakeConditionVariable(cv); pReleaseSRWLockExclusive(&condvar_srwlock); while (condvar_seq < 11) Sleep(1); pAcquireSRWLockShared(&condvar_srwlock); - pWakeConditionVariable(&condvar_base); + pWakeConditionVariable(cv); pReleaseSRWLockShared(&condvar_srwlock); while (condvar_seq < 12) Sleep(1); Sleep(50); /* ensure that consumer waits for cond variable */ pAcquireSRWLockShared(&condvar_srwlock); - pWakeConditionVariable(&condvar_base); + pWakeConditionVariable(cv); pReleaseSRWLockShared(&condvar_srwlock); return 0; } -static DWORD WINAPI condvar_base_consumer(LPVOID x) { +static DWORD WINAPI condvar_base_consumer(void *arg) +{ + CONDITION_VARIABLE *cv = arg; BOOL ret; while (condvar_seq < 2) Sleep(1); /* wake was emitted, but we were not sleeping */ EnterCriticalSection (&condvar_crit); - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 10); LeaveCriticalSection (&condvar_crit); ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n"); ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError()); @@ -1811,33 +1824,33 @@ static DWORD WINAPI condvar_base_consumer(LPVOID x) { /* wake all was emitted, but we were not sleeping */ EnterCriticalSection (&condvar_crit); - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 10); LeaveCriticalSection (&condvar_crit); ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n"); ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError()); EnterCriticalSection (&condvar_crit); condvar_seq = 5; - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 200); LeaveCriticalSection (&condvar_crit); ok (ret, "SleepConditionVariableCS should return TRUE on good wake\n"); EnterCriticalSection (&condvar_crit); condvar_seq = 6; - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 200); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 200); LeaveCriticalSection (&condvar_crit); ok (ret, "SleepConditionVariableCS should return TRUE on good wakeall\n"); condvar_seq = 7; EnterCriticalSection (&condvar_crit); - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 10); LeaveCriticalSection (&condvar_crit); ok (!ret, "SleepConditionVariableCS should return FALSE on out of band wake\n"); ok (GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableCS should return ERROR_TIMEOUT on out of band wake, not %d\n", GetLastError()); EnterCriticalSection (&condvar_crit); condvar_seq = 8; - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 20); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 20); LeaveCriticalSection (&condvar_crit); ok (ret, "SleepConditionVariableCS should still return TRUE on crit unlock delay\n"); @@ -1851,25 +1864,25 @@ static DWORD WINAPI condvar_base_consumer(LPVOID x) { pAcquireSRWLockExclusive(&condvar_srwlock); condvar_seq = 9; - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 200, 0); pReleaseSRWLockExclusive(&condvar_srwlock); ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n"); pAcquireSRWLockShared(&condvar_srwlock); condvar_seq = 10; - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED); pReleaseSRWLockShared(&condvar_srwlock); ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n"); pAcquireSRWLockExclusive(&condvar_srwlock); condvar_seq = 11; - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, 0); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 200, 0); pReleaseSRWLockExclusive(&condvar_srwlock); ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n"); pAcquireSRWLockShared(&condvar_srwlock); condvar_seq = 12; - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 200, CONDITION_VARIABLE_LOCKMODE_SHARED); pReleaseSRWLockShared(&condvar_srwlock); ok (ret, "pSleepConditionVariableSRW should return TRUE on good wake\n"); @@ -1877,12 +1890,12 @@ static DWORD WINAPI condvar_base_consumer(LPVOID x) { return 0; } -static void test_condvars_base(void) { +static void test_condvars_base(RTL_CONDITION_VARIABLE *cv) +{ HANDLE hp, hc; DWORD dummy; BOOL ret; - if (!pInitializeConditionVariable) { /* function is not yet in XP, only in newer Windows */ win_skip("no condition variable support.\n"); @@ -1895,7 +1908,7 @@ static void test_condvars_base(void) { pInitializeSRWLock(&condvar_srwlock); EnterCriticalSection (&condvar_crit); - ret = pSleepConditionVariableCS(&condvar_base, &condvar_crit, 10); + ret = pSleepConditionVariableCS(cv, &condvar_crit, 10); LeaveCriticalSection (&condvar_crit); ok (!ret, "SleepConditionVariableCS should return FALSE on untriggered condvar\n"); @@ -1904,23 +1917,23 @@ static void test_condvars_base(void) { if (pInitializeSRWLock) { pAcquireSRWLockExclusive(&condvar_srwlock); - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, 0); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 10, 0); pReleaseSRWLockExclusive(&condvar_srwlock); ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n"); ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError()); pAcquireSRWLockShared(&condvar_srwlock); - ret = pSleepConditionVariableSRW(&condvar_base, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED); + ret = pSleepConditionVariableSRW(cv, &condvar_srwlock, 10, CONDITION_VARIABLE_LOCKMODE_SHARED); pReleaseSRWLockShared(&condvar_srwlock); ok(!ret, "SleepConditionVariableSRW should return FALSE on untriggered condvar\n"); ok(GetLastError() == ERROR_TIMEOUT, "SleepConditionVariableSRW should return ERROR_TIMEOUT on untriggered condvar, not %d\n", GetLastError()); } - - hp = CreateThread(NULL, 0, condvar_base_producer, NULL, 0, &dummy); - hc = CreateThread(NULL, 0, condvar_base_consumer, NULL, 0, &dummy); + condvar_seq = 0; + hp = CreateThread(NULL, 0, condvar_base_producer, cv, 0, &dummy); + hc = CreateThread(NULL, 0, condvar_base_consumer, cv, 0, &dummy); condvar_seq = 1; /* go */ @@ -2728,7 +2741,8 @@ START_TEST(sync) test_WaitForSingleObject(); test_WaitForMultipleObjects(); test_initonce(); - test_condvars_base(); + test_condvars_base(&aligned_cv); + test_condvars_base(&unaligned_cv.cv); test_condvars_consumer_producer(); test_srwlock_base(); test_srwlock_example(); diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 0dc6fc3390..302b4cc7e0 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -115,6 +115,16 @@ static inline int use_futexes(void) return supported; } +static int *get_futex(void **ptr) +{ + if (sizeof(void *) == 8) + return (int *)((((ULONG_PTR)ptr) + 3) & ~3); + else if (!(((ULONG_PTR)ptr) & 3)) + return (int *)ptr; + else + return NULL; +} + static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGER *timeout ) { LARGE_INTEGER now; @@ -2179,32 +2189,83 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) } #ifdef __linux__ -static NTSTATUS fast_wait_cv( RTL_CONDITION_VARIABLE *variable, int val, const LARGE_INTEGER *timeout ) +static NTSTATUS fast_wait_cv( int *futex, int val, const LARGE_INTEGER *timeout ) { struct timespec timespec; int ret; - if (!use_futexes()) - return STATUS_NOT_IMPLEMENTED; - if (timeout && timeout->QuadPart != TIMEOUT_INFINITE) { timespec_from_timeout( ×pec, timeout ); - ret = futex_wait( (int *)&variable->Ptr, val, ×pec ); + ret = futex_wait( futex, val, ×pec ); } else - ret = futex_wait( (int *)&variable->Ptr, val, NULL ); + ret = futex_wait( futex, val, NULL ); if (ret == -1 && errno == ETIMEDOUT) return STATUS_TIMEOUT; return STATUS_WAIT_0; } +static NTSTATUS fast_sleep_cs_cv( RTL_CONDITION_VARIABLE *variable, + RTL_CRITICAL_SECTION *cs, const LARGE_INTEGER *timeout ) +{ + NTSTATUS status; + int val, *futex; + + if (!use_futexes()) + return STATUS_NOT_IMPLEMENTED; + + if (!(futex = get_futex( &variable->Ptr ))) + return STATUS_NOT_IMPLEMENTED; + + val = *futex; + + RtlLeaveCriticalSection( cs ); + status = fast_wait_cv( futex, val, timeout ); + RtlEnterCriticalSection( cs ); + return status; +} + +static NTSTATUS fast_sleep_srw_cv( RTL_CONDITION_VARIABLE *variable, + RTL_SRWLOCK *lock, const LARGE_INTEGER *timeout, ULONG flags ) +{ + NTSTATUS status; + int val, *futex; + + if (!use_futexes()) + return STATUS_NOT_IMPLEMENTED; + + if (!(futex = get_futex( &variable->Ptr ))) + return STATUS_NOT_IMPLEMENTED; + + val = *futex; + + if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + RtlReleaseSRWLockShared( lock ); + else + RtlReleaseSRWLockExclusive( lock ); + + status = fast_wait_cv( futex, val, timeout ); + + if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) + RtlAcquireSRWLockShared( lock ); + else + RtlAcquireSRWLockExclusive( lock ); + return status; +} + static NTSTATUS fast_wake_cv( RTL_CONDITION_VARIABLE *variable, int count ) { + int *futex; + if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; - futex_wake( (int *)&variable->Ptr, count ); + if (!(futex = get_futex( &variable->Ptr ))) + return STATUS_NOT_IMPLEMENTED; + + interlocked_xchg_add( futex, 1 ); + futex_wake( futex, count ); return STATUS_SUCCESS; } #else @@ -2252,9 +2313,11 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable ) */ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) { - interlocked_xchg_add( (int *)&variable->Ptr, 1 ); if (fast_wake_cv( variable, 1 ) == STATUS_NOT_IMPLEMENTED) + { + interlocked_xchg_add( (int *)&variable->Ptr, 1 ); RtlWakeAddressSingle( variable ); + } } /*********************************************************************** @@ -2264,9 +2327,11 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) */ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable ) { - interlocked_xchg_add( (int *)&variable->Ptr, 1 ); if (fast_wake_cv( variable, INT_MAX ) == STATUS_NOT_IMPLEMENTED) + { + interlocked_xchg_add( (int *)&variable->Ptr, 1 ); RtlWakeAddressAll( variable ); + } } /*********************************************************************** @@ -2288,15 +2353,15 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R const LARGE_INTEGER *timeout ) { NTSTATUS status; - int val = *(int *)&variable->Ptr; - - RtlLeaveCriticalSection( crit ); + int val; - if ((status = fast_wait_cv( variable, val, timeout )) == STATUS_NOT_IMPLEMENTED) - status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout ); + if ((status = fast_sleep_cs_cv( variable, crit, timeout )) != STATUS_NOT_IMPLEMENTED) + return status; + val = *(int *)&variable->Ptr; + RtlLeaveCriticalSection( crit ); + status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout ); RtlEnterCriticalSection( crit ); - return status; } @@ -2323,15 +2388,19 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, const LARGE_INTEGER *timeout, ULONG flags ) { NTSTATUS status; - int val = *(int *)&variable->Ptr; + int val; + + if ((status = fast_sleep_srw_cv( variable, lock, timeout, flags )) != STATUS_NOT_IMPLEMENTED) + return status; + + val = *(int *)&variable->Ptr; if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) RtlReleaseSRWLockShared( lock ); else RtlReleaseSRWLockExclusive( lock ); - if ((status = fast_wait_cv( variable, val, timeout )) == STATUS_NOT_IMPLEMENTED) - status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout ); + status = RtlWaitOnAddress( &variable->Ptr, &val, sizeof(int), timeout ); if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) RtlAcquireSRWLockShared( lock ); -- 2.24.1
Signed-off-by: Zebediah Figura <z.figura12(a)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
Hi, While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=62679 Your paranoid android. === debian10 (32 bit report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 9 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 2 times). === debian10 (32 bit French report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 11 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 3 times). === debian10 (32 bit Japanese:Japan report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 9 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 2 times). === debian10 (32 bit Chinese:China report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 11 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 3 times). === debian10 (32 bit WoW report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 9 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 2 times). === debian10 (64 bit WoW report) === kernel32: sync.c:2371: Test failed: thread commands were executed in the wrong order (occurred 9 times). sync.c:2375: Test failed: AcquireSRWLockExclusive didn't block when called multiple times from the same thread (occurred 2 times). sync.c:2379: Test failed: AcquireSRWLockShared didn't block when the same thread holds an exclusive lock (occurred 2 times). sync.c:2383: Test failed: AcquireSRWLockExclusive didn't block when the same thread holds a shared lock (occurred 2 times). sync.c:2387: Test failed: AcquireSRWLockExclusive didn't block when a second thread holds the exclusive lock (occurred 2 times). sync.c:2391: Test failed: thread waiting for exclusive access to the SHMLock was not preferred (occurred 2 times).
participants (2)
-
Marvin -
Zebediah Figura