mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Rebase against dc214bfad723efeea96a5d33eb7fc0802dc34be9
This commit is contained in:
parent
e2c2447841
commit
a23c076055
@ -1,4 +1,4 @@
|
||||
From 5633db2ec821eac01998f6bb1012372865f3db40 Mon Sep 17 00:00:00 2001
|
||||
From f46ec161cac98de03cae27a70cea043538359cc2 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Mon, 3 Apr 2017 05:30:27 +0200
|
||||
Subject: [PATCH] ntdll: Implement HashLinks field in LDR module data.
|
||||
@ -10,7 +10,7 @@ Subject: [PATCH] ntdll: Implement HashLinks field in LDR module data.
|
||||
3 files changed, 145 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
|
||||
index 35c6b3c0996..17d742daaa7 100644
|
||||
index dc2d34c9b00..753159a04ce 100644
|
||||
--- a/dlls/kernel32/tests/loader.c
|
||||
+++ b/dlls/kernel32/tests/loader.c
|
||||
@@ -30,6 +30,7 @@
|
||||
@ -21,7 +21,7 @@ index 35c6b3c0996..17d742daaa7 100644
|
||||
#include "wine/test.h"
|
||||
#include "delayloadhandler.h"
|
||||
|
||||
@@ -3934,6 +3935,79 @@ static void test_LoadPackagedLibrary(void)
|
||||
@@ -4064,6 +4065,79 @@ static void test_LoadPackagedLibrary(void)
|
||||
h, GetLastError());
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ index 35c6b3c0996..17d742daaa7 100644
|
||||
START_TEST(loader)
|
||||
{
|
||||
int argc;
|
||||
@@ -4006,10 +4080,12 @@ START_TEST(loader)
|
||||
@@ -4137,10 +4211,12 @@ START_TEST(loader)
|
||||
test_InMemoryOrderModuleList();
|
||||
test_LoadPackagedLibrary();
|
||||
test_wow64_redirection();
|
||||
@ -115,10 +115,10 @@ index 35c6b3c0996..17d742daaa7 100644
|
||||
test_Loader();
|
||||
}
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index b946416734a..5037318eb98 100644
|
||||
index a1cc673d1fe..7328c601c9c 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -114,6 +114,9 @@ static const char * const reason_names[] =
|
||||
@@ -121,6 +121,9 @@ static const char * const reason_names[] =
|
||||
|
||||
static const WCHAR dllW[] = {'.','d','l','l',0};
|
||||
|
||||
@ -128,7 +128,7 @@ index b946416734a..5037318eb98 100644
|
||||
/* internal representation of 32bit modules. per process. */
|
||||
typedef struct _wine_modref
|
||||
{
|
||||
@@ -451,6 +454,52 @@ static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
|
||||
@@ -460,6 +463,52 @@ static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +181,7 @@ index b946416734a..5037318eb98 100644
|
||||
/*************************************************************************
|
||||
* get_modref
|
||||
*
|
||||
@@ -1201,7 +1250,12 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
|
||||
@@ -1218,7 +1267,12 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList,
|
||||
&wm->ldr.InMemoryOrderModuleList);
|
||||
@ -194,7 +194,7 @@ index b946416734a..5037318eb98 100644
|
||||
|
||||
if (!(nt->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_NX_COMPAT))
|
||||
{
|
||||
@@ -1857,6 +1911,7 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||
@@ -1912,6 +1966,7 @@ static void load_builtin_callback( void *module, const char *filename )
|
||||
/* the module has only be inserted in the load & memory order lists */
|
||||
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||
@ -202,7 +202,7 @@ index b946416734a..5037318eb98 100644
|
||||
/* FIXME: free the modref */
|
||||
builtin_load_info->status = STATUS_DLL_NOT_FOUND;
|
||||
return;
|
||||
@@ -2380,6 +2435,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam
|
||||
@@ -2435,6 +2490,7 @@ static NTSTATUS load_native_dll( LPCWSTR load_path, const UNICODE_STRING *nt_nam
|
||||
/* the module has only be inserted in the load & memory order lists */
|
||||
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||
@ -210,7 +210,7 @@ index b946416734a..5037318eb98 100644
|
||||
|
||||
/* FIXME: there are several more dangling references
|
||||
* left. Including dlls loaded by this dll before the
|
||||
@@ -3568,6 +3624,7 @@ static void free_modref( WINE_MODREF *wm )
|
||||
@@ -3627,6 +3683,7 @@ static void free_modref( WINE_MODREF *wm )
|
||||
{
|
||||
RemoveEntryList(&wm->ldr.InLoadOrderModuleList);
|
||||
RemoveEntryList(&wm->ldr.InMemoryOrderModuleList);
|
||||
@ -218,7 +218,7 @@ index b946416734a..5037318eb98 100644
|
||||
if (wm->ldr.InInitializationOrderModuleList.Flink)
|
||||
RemoveEntryList(&wm->ldr.InInitializationOrderModuleList);
|
||||
|
||||
@@ -4245,6 +4302,7 @@ void __wine_process_init(void)
|
||||
@@ -4376,6 +4433,7 @@ void __wine_process_init(void)
|
||||
SIZE_T info_size;
|
||||
TEB *teb = thread_init();
|
||||
PEB *peb = teb->Peb;
|
||||
@ -226,7 +226,7 @@ index b946416734a..5037318eb98 100644
|
||||
|
||||
/* setup the server connection */
|
||||
server_init_process();
|
||||
@@ -4266,6 +4324,10 @@ void __wine_process_init(void)
|
||||
@@ -4399,6 +4457,10 @@ void __wine_process_init(void)
|
||||
load_global_options();
|
||||
version_init();
|
||||
|
||||
@ -235,9 +235,9 @@ index b946416734a..5037318eb98 100644
|
||||
+ InitializeListHead(&hash_table[i]);
|
||||
+
|
||||
/* setup the load callback and create ntdll modref */
|
||||
wine_dll_set_callback( load_builtin_callback );
|
||||
|
||||
@@ -4338,5 +4400,8 @@ void __wine_process_init(void)
|
||||
RtlInitUnicodeString( &nt_name, ntdllW );
|
||||
default_load_info.filename = &nt_name;
|
||||
@@ -4486,5 +4548,8 @@ void __wine_process_init(void)
|
||||
teb->Tib.StackLimit = stack.StackLimit;
|
||||
teb->DeallocationStack = stack.DeallocationStack;
|
||||
|
||||
@ -247,10 +247,10 @@ index b946416734a..5037318eb98 100644
|
||||
server_init_process_done();
|
||||
}
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index b9fac4bfca3..6ec99aab8fd 100644
|
||||
index 3087f55089d..ee439d1986c 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -2268,8 +2268,8 @@ typedef struct _LDR_MODULE
|
||||
@@ -2297,8 +2297,8 @@ typedef struct _LDR_MODULE
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
@ -260,7 +260,7 @@ index b9fac4bfca3..6ec99aab8fd 100644
|
||||
ULONG TimeDateStamp;
|
||||
HANDLE ActivationContext;
|
||||
PVOID PatchInformation;
|
||||
@@ -2279,6 +2279,9 @@ typedef struct _LDR_MODULE
|
||||
@@ -2308,6 +2308,9 @@ typedef struct _LDR_MODULE
|
||||
PVOID ContextInformation;
|
||||
ULONG_PTR OriginalBase;
|
||||
LARGE_INTEGER LoadTime;
|
||||
@ -271,5 +271,5 @@ index b9fac4bfca3..6ec99aab8fd 100644
|
||||
|
||||
typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA
|
||||
--
|
||||
2.26.0
|
||||
2.25.1
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
From 8fcd62774c95cecf71bac1210767dc7120e3e4ae Mon Sep 17 00:00:00 2001
|
||||
From: Myah Caron <qsniyg@protonmail.com>
|
||||
Date: Thu, 2 Apr 2020 06:25:23 +0000
|
||||
Subject: [PATCH] ntdll: Cache LDR_IMAGE_IS_DLL for InitDLL
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48817
|
||||
Signed-off-by: Myah Caron <qsniyg@protonmail.com>
|
||||
---
|
||||
dlls/ntdll/loader.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 7090990c638..6fe7de58854 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -133,6 +133,7 @@ typedef struct _wine_modref
|
||||
int alloc_deps;
|
||||
int nDeps;
|
||||
struct _wine_modref **deps;
|
||||
+ BOOL is_dll;
|
||||
} WINE_MODREF;
|
||||
|
||||
/* info about the current builtin dll load */
|
||||
@@ -1255,6 +1256,9 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
|
||||
wm->ldr.EntryPoint = (char *)hModule + nt->OptionalHeader.AddressOfEntryPoint;
|
||||
}
|
||||
|
||||
+ /* The flags can be modified later */
|
||||
+ wm->is_dll = !!(wm->ldr.Flags & LDR_IMAGE_IS_DLL);
|
||||
+
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList,
|
||||
&wm->ldr.InLoadOrderModuleList);
|
||||
InsertTailList(&NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList,
|
||||
@@ -1372,7 +1376,7 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
||||
|
||||
if (wm->ldr.Flags & LDR_DONT_RESOLVE_REFS) return STATUS_SUCCESS;
|
||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
|
||||
- if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return STATUS_SUCCESS;
|
||||
+ if (!entry || !(wm->is_dll)) return STATUS_SUCCESS;
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
{
|
||||
--
|
||||
2.25.1
|
||||
|
@ -1 +0,0 @@
|
||||
Fixes: [48817] ntdll: Cache LDR_IMAGE_IS_DLL for InitDLL
|
@ -1,4 +1,4 @@
|
||||
From 7b215b4d87481ce9e30090b6b17e2f7b48937473 Mon Sep 17 00:00:00 2001
|
||||
From 386a69b025194f9c6a8bb3856fbab71b3a4672ce Mon Sep 17 00:00:00 2001
|
||||
From: Qian Hong <qhong@codeweavers.com>
|
||||
Date: Wed, 9 Sep 2015 05:31:18 +0800
|
||||
Subject: [PATCH] ntdll: Initialize mod_name to zero.
|
||||
@ -8,12 +8,12 @@ Subject: [PATCH] ntdll: Initialize mod_name to zero.
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 6fe7de58854..13e5fd3f877 100644
|
||||
index b0307ca0674..7a113211603 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -1378,6 +1378,8 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
||||
@@ -1382,6 +1382,8 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
|
||||
if (!entry || !(wm->is_dll)) return STATUS_SUCCESS;
|
||||
if (!entry) return STATUS_SUCCESS;
|
||||
|
||||
+ memset( mod_name, 0, sizeof(mod_name) );
|
||||
+
|
||||
|
@ -1,452 +0,0 @@
|
||||
From 7c7d16aa4ee05ed3011ddbda68df2b9696d8da46 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 30 Dec 2019 17:17:47 -0600
|
||||
Subject: [PATCH] ntdll: Handle unaligned condition variables when using
|
||||
futexes.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48389
|
||||
---
|
||||
dlls/kernel32/tests/sync.c | 76 ++++++++++++++----------
|
||||
dlls/ntdll/sync.c | 117 +++++++++++++++++++++++++++++++------
|
||||
2 files changed, 144 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
|
||||
index 40cad1c4c50..477a35287d3 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 2b5b6ce44a5..93a947e452a 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,35 +2189,98 @@ 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
|
||||
+static NTSTATUS fast_sleep_srw_cv( RTL_CONDITION_VARIABLE *variable,
|
||||
+ RTL_SRWLOCK *lock, const LARGE_INTEGER *timeout, ULONG flags )
|
||||
+{
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
+static NTSTATUS fast_sleep_cs_cv( RTL_CONDITION_VARIABLE *variable,
|
||||
+ RTL_CRITICAL_SECTION *cs, const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ return STATUS_NOT_IMPLEMENTED;
|
||||
+}
|
||||
+
|
||||
static NTSTATUS fast_wait_cv( RTL_CONDITION_VARIABLE *variable, int val, const LARGE_INTEGER *timeout )
|
||||
{
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
@@ -2252,9 +2325,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 +2339,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 +2365,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 +2400,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.17.1
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 9b4b22164e5e76f7e6efcc13d8a7f0971e2af4dd Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 30 Dec 2019 17:17:48 -0600
|
||||
Subject: [PATCH 2/3] ntdll: Handle unaligned SRW locks when using keyed
|
||||
events.
|
||||
|
||||
---
|
||||
dlls/ntdll/sync.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index ac324ebbbe..5b0f5b903c 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -2035,11 +2035,11 @@ static NTSTATUS fast_release_srw_shared( RTL_SRWLOCK *lock )
|
||||
#define SRWLOCK_RES_SHARED 0x00000001
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
-#define srwlock_key_exclusive(lock) (&lock->Ptr)
|
||||
-#define srwlock_key_shared(lock) ((void *)((char *)&lock->Ptr + 2))
|
||||
+#define srwlock_key_exclusive(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 1) & ~1))
|
||||
+#define srwlock_key_shared(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 3) & ~1))
|
||||
#else
|
||||
-#define srwlock_key_exclusive(lock) ((void *)((char *)&lock->Ptr + 2))
|
||||
-#define srwlock_key_shared(lock) (&lock->Ptr)
|
||||
+#define srwlock_key_exclusive(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 3) & ~1))
|
||||
+#define srwlock_key_shared(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 1) & ~1))
|
||||
#endif
|
||||
|
||||
static inline void srwlock_check_invalid( unsigned int val )
|
||||
--
|
||||
2.24.1
|
||||
|
@ -1,666 +0,0 @@
|
||||
From afff343503663273568f6343504d2226defae90c Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 30 Dec 2019 17:17:49 -0600
|
||||
Subject: [PATCH 3/3] ntdll: Handle unaligned SRW locks when using futexes.
|
||||
|
||||
---
|
||||
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 fb93dfdc53..494858dc37 100644
|
||||
--- a/dlls/kernel32/tests/sync.c
|
||||
+++ b/dlls/kernel32/tests/sync.c
|
||||
@@ -2320,7 +2320,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;
|
||||
@@ -2333,6 +2333,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
|
||||
*
|
||||
@@ -2404,49 +2412,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);
|
||||
|
||||
@@ -2455,7 +2465,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)
|
||||
@@ -2463,125 +2473,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);
|
||||
|
||||
@@ -2591,12 +2603,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)
|
||||
@@ -2604,20 +2616,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);
|
||||
@@ -2625,47 +2637,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)
|
||||
@@ -2674,8 +2686,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 */
|
||||
@@ -2683,10 +2697,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);
|
||||
|
||||
@@ -2702,7 +2716,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;
|
||||
@@ -2714,12 +2728,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)
|
||||
@@ -3199,7 +3214,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 5b0f5b903c..4ec51558ca 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -1755,14 +1755,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))
|
||||
@@ -1776,31 +1779,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))
|
||||
@@ -1816,12 +1822,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;
|
||||
@@ -1829,14 +1835,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))
|
||||
@@ -1852,23 +1861,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))
|
||||
@@ -1884,12 +1896,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;
|
||||
@@ -1897,17 +1909,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;
|
||||
}
|
||||
|
||||
@@ -1915,43 +1930,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
|
||||
|
@ -1,2 +0,0 @@
|
||||
Fixes: [48389] Detroit: Become Human has poor performance (use of unaligned futexes for condition variables on Linux)
|
||||
|
@ -52,7 +52,7 @@ usage()
|
||||
# Get the upstream commit sha
|
||||
upstream_commit()
|
||||
{
|
||||
echo "5e75310837e5ec77ebc361d689ea3279fa49ebac"
|
||||
echo "dc214bfad723efeea96a5d33eb7fc0802dc34be9"
|
||||
}
|
||||
|
||||
# Show version information
|
||||
@ -185,7 +185,6 @@ patch_enable_all ()
|
||||
enable_ntdll_Hide_Wine_Exports="$1"
|
||||
enable_ntdll_Interrupt_0x2e="$1"
|
||||
enable_ntdll_Junction_Points="$1"
|
||||
enable_ntdll_LDR_IMAGE_IS_DLL="$1"
|
||||
enable_ntdll_LDR_MODULE="$1"
|
||||
enable_ntdll_Manifest_Range="$1"
|
||||
enable_ntdll_NtAccessCheck="$1"
|
||||
@ -217,7 +216,6 @@ patch_enable_all ()
|
||||
enable_ntdll_avoid_fstatat="$1"
|
||||
enable_ntdll_ext4_case_folder="$1"
|
||||
enable_ntdll_set_full_cpu_context="$1"
|
||||
enable_ntdll_unaligned_futex="$1"
|
||||
enable_ntdll_x86_64_SegDs="$1"
|
||||
enable_ntoskrnl_Stubs="$1"
|
||||
enable_nvapi_Stub_DLL="$1"
|
||||
@ -667,9 +665,6 @@ patch_enable ()
|
||||
ntdll-Junction_Points)
|
||||
enable_ntdll_Junction_Points="$2"
|
||||
;;
|
||||
ntdll-LDR_IMAGE_IS_DLL)
|
||||
enable_ntdll_LDR_IMAGE_IS_DLL="$2"
|
||||
;;
|
||||
ntdll-LDR_MODULE)
|
||||
enable_ntdll_LDR_MODULE="$2"
|
||||
;;
|
||||
@ -763,9 +758,6 @@ patch_enable ()
|
||||
ntdll-set_full_cpu_context)
|
||||
enable_ntdll_set_full_cpu_context="$2"
|
||||
;;
|
||||
ntdll-unaligned-futex)
|
||||
enable_ntdll_unaligned_futex="$2"
|
||||
;;
|
||||
ntdll-x86_64_SegDs)
|
||||
enable_ntdll_x86_64_SegDs="$2"
|
||||
;;
|
||||
@ -4665,21 +4657,6 @@ if test "$enable_ntdll_Interrupt_0x2e" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-LDR_IMAGE_IS_DLL
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#48817] ntdll: Cache LDR_IMAGE_IS_DLL for InitDLL
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/loader.c
|
||||
# |
|
||||
if test "$enable_ntdll_LDR_IMAGE_IS_DLL" -eq 1; then
|
||||
patch_apply ntdll-LDR_IMAGE_IS_DLL/0001-ntdll-Cache-LDR_IMAGE_IS_DLL-for-InitDLL.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Myah Caron", "ntdll: Cache LDR_IMAGE_IS_DLL for InitDLL.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-Manifest_Range
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -5094,25 +5071,6 @@ if test "$enable_ntdll_set_full_cpu_context" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-unaligned-futex
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#48389] Detroit: Become Human has poor performance (use of unaligned futexes for condition variables on Linux)
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/tests/sync.c, dlls/ntdll/sync.c
|
||||
# |
|
||||
if test "$enable_ntdll_unaligned_futex" -eq 1; then
|
||||
patch_apply ntdll-unaligned-futex/0001-ntdll-Handle-unaligned-condition-variables-when-usin.patch
|
||||
patch_apply ntdll-unaligned-futex/0002-ntdll-Handle-unaligned-SRW-locks-when-using-keyed-ev.patch
|
||||
patch_apply ntdll-unaligned-futex/0003-ntdll-Handle-unaligned-SRW-locks-when-using-futexes.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Zebediah Figura", "ntdll: Handle unaligned condition variables when using futexes.", 1 },';
|
||||
printf '%s\n' '+ { "Zebediah Figura", "ntdll: Handle unaligned SRW locks when using keyed events.", 1 },';
|
||||
printf '%s\n' '+ { "Zebediah Figura", "ntdll: Handle unaligned SRW locks when using futexes.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset ntdll-x86_64_SegDs
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b291e0c2c119d24b4a5119604d84bd62023a5c71 Mon Sep 17 00:00:00 2001
|
||||
From 503f898967ffdf8e3b7eff12faf2adf4f2fc4a25 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Wed, 8 Aug 2018 20:00:15 -0500
|
||||
Subject: [PATCH] ntdll: Add a stub implementation of Wow64Transition.
|
||||
@ -9,10 +9,10 @@ Subject: [PATCH] ntdll: Add a stub implementation of Wow64Transition.
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 5e4ef0f2b8d..13a9b6b8707 100644
|
||||
index 3586bd44d96..1f74b029cac 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -4441,18 +4441,20 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
|
||||
@@ -4418,12 +4418,14 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -24,8 +24,10 @@ index 5e4ef0f2b8d..13a9b6b8707 100644
|
||||
void __wine_process_init(void)
|
||||
{
|
||||
+ static const WCHAR wow64cpuW[] = {'w','o','w','6','4','c','p','u','.','d','l','l',0};
|
||||
static const WCHAR kernel32W[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\',
|
||||
static const WCHAR ntdllW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
|
||||
's','y','s','t','e','m','3','2','\\',
|
||||
'n','t','d','l','l','.','d','l','l',0};
|
||||
@@ -4432,7 +4434,7 @@ void __wine_process_init(void)
|
||||
'k','e','r','n','e','l','3','2','.','d','l','l',0};
|
||||
RTL_USER_PROCESS_PARAMETERS *params;
|
||||
ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION runlevel;
|
||||
@ -34,7 +36,7 @@ index 5e4ef0f2b8d..13a9b6b8707 100644
|
||||
NTSTATUS status;
|
||||
ANSI_STRING func_name;
|
||||
UNICODE_STRING nt_name;
|
||||
@@ -4498,7 +4500,15 @@ void __wine_process_init(void)
|
||||
@@ -4480,7 +4482,15 @@ void __wine_process_init(void)
|
||||
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
|
||||
exit(1);
|
||||
}
|
||||
@ -51,10 +53,10 @@ index 5e4ef0f2b8d..13a9b6b8707 100644
|
||||
0, (void **)&kernel32_start_process )) != STATUS_SUCCESS)
|
||||
{
|
||||
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
||||
index bb634af5e46..44bbdcefb2a 100644
|
||||
index 39a2407e5bd..dc70320653b 100644
|
||||
--- a/dlls/ntdll/ntdll.spec
|
||||
+++ b/dlls/ntdll/ntdll.spec
|
||||
@@ -1090,6 +1090,7 @@
|
||||
@@ -1100,6 +1100,7 @@
|
||||
@ stdcall WinSqmIsOptedIn()
|
||||
@ stdcall WinSqmSetDWORD(ptr long long)
|
||||
@ stdcall WinSqmStartSession(ptr long long)
|
||||
@ -63,5 +65,5 @@ index bb634af5e46..44bbdcefb2a 100644
|
||||
@ stdcall -private ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
|
||||
@ stdcall -private ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) NtAccessCheckAndAuditAlarm
|
||||
--
|
||||
2.17.1
|
||||
2.25.1
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user