mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
ntdll-NtAlertThreadByThreadId: Use flat two-dimensional arrays indexed by thread ID on both the PE and Unix side.
This should be less invasive and hopefully improve performance.
This commit is contained in:
parent
7d496bf02c
commit
a1a2d65488
@ -1,13 +1,14 @@
|
||||
From b2fef9e91f2625ccb700963ac87b47eeb3138a9a Mon Sep 17 00:00:00 2001
|
||||
From 339c0672e50344eabb605e13f3c58f7f534417dc Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Thu, 9 Jan 2020 13:44:01 -0600
|
||||
Subject: [PATCH] ntdll/tests: Move some tests to a new sync.c file.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/Makefile.in | 1 +
|
||||
dlls/ntdll/tests/om.c | 494 -------------------------------
|
||||
dlls/ntdll/tests/sync.c | 547 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 548 insertions(+), 494 deletions(-)
|
||||
dlls/ntdll/tests/om.c | 573 -------------------------------
|
||||
dlls/ntdll/tests/sync.c | 630 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 631 insertions(+), 573 deletions(-)
|
||||
create mode 100644 dlls/ntdll/tests/sync.c
|
||||
|
||||
diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in
|
||||
@ -23,7 +24,7 @@ index ed15c51339f..9a99c01bd7c 100644
|
||||
time.c \
|
||||
virtual.c
|
||||
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
|
||||
index 7d9ca47be12..7759736ca1c 100644
|
||||
index 7d9ca47be12..d06812a9529 100644
|
||||
--- a/dlls/ntdll/tests/om.c
|
||||
+++ b/dlls/ntdll/tests/om.c
|
||||
@@ -30,10 +30,6 @@
|
||||
@ -37,7 +38,7 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
|
||||
static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
|
||||
static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
|
||||
@@ -44,8 +40,6 @@ static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_A
|
||||
@@ -44,11 +40,8 @@ static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_A
|
||||
ULONG, ULONG, ULONG, PLARGE_INTEGER );
|
||||
static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
|
||||
static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
|
||||
@ -45,8 +46,11 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
-static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, PLONG );
|
||||
static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
|
||||
static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
|
||||
static NTSTATUS (WINAPI *pNtQuerySemaphore)( PHANDLE, SEMAPHORE_INFORMATION_CLASS, PVOID, ULONG, PULONG );
|
||||
@@ -67,15 +61,9 @@ static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,U
|
||||
-static NTSTATUS (WINAPI *pNtQuerySemaphore)( PHANDLE, SEMAPHORE_INFORMATION_CLASS, PVOID, ULONG, PULONG );
|
||||
static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
|
||||
static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
|
||||
static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
|
||||
@@ -67,15 +60,9 @@ static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,U
|
||||
static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
|
||||
static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
|
||||
static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
|
||||
@ -62,7 +66,7 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
static NTSTATUS (WINAPI *pNtOpenProcess)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const CLIENT_ID * );
|
||||
static NTSTATUS (WINAPI *pNtCreateDebugObject)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, ULONG );
|
||||
static NTSTATUS (WINAPI *pNtGetNextThread)(HANDLE process, HANDLE thread, ACCESS_MASK access, ULONG attributes,
|
||||
@@ -1722,286 +1710,6 @@ static void test_type_mismatch(void)
|
||||
@@ -1722,286 +1709,6 @@ static void test_type_mismatch(void)
|
||||
pNtClose( h );
|
||||
}
|
||||
|
||||
@ -349,7 +353,7 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
static void test_null_device(void)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
@@ -2075,119 +1783,6 @@ static void test_null_device(void)
|
||||
@@ -2075,268 +1782,6 @@ static void test_null_device(void)
|
||||
CloseHandle(ov.hEvent);
|
||||
}
|
||||
|
||||
@ -466,13 +470,82 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
- NtClose( mutant );
|
||||
-}
|
||||
-
|
||||
static void test_semaphore(void)
|
||||
{
|
||||
SEMAPHORE_BASIC_INFORMATION info;
|
||||
@@ -2264,79 +1859,6 @@ static void test_semaphore(void)
|
||||
NtClose( semaphore );
|
||||
}
|
||||
|
||||
-static void test_semaphore(void)
|
||||
-{
|
||||
- SEMAPHORE_BASIC_INFORMATION info;
|
||||
- OBJECT_ATTRIBUTES attr;
|
||||
- UNICODE_STRING str;
|
||||
- NTSTATUS status;
|
||||
- HANDLE semaphore;
|
||||
- ULONG prev;
|
||||
- ULONG len;
|
||||
- DWORD ret;
|
||||
-
|
||||
- pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_semaphore");
|
||||
- InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
-
|
||||
- status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 2, 1);
|
||||
- ok( status == STATUS_INVALID_PARAMETER, "Failed to create Semaphore(%08x)\n", status );
|
||||
- status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 1, 2);
|
||||
- ok( status == STATUS_SUCCESS, "Failed to create Semaphore(%08x)\n", status );
|
||||
-
|
||||
- /* bogus */
|
||||
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, 0, NULL);
|
||||
- ok( status == STATUS_INFO_LENGTH_MISMATCH,
|
||||
- "Failed to NtQuerySemaphore, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
|
||||
- status = pNtQuerySemaphore(semaphore, 0x42, &info, sizeof(info), NULL);
|
||||
- ok( status == STATUS_INVALID_INFO_CLASS,
|
||||
- "Failed to NtQuerySemaphore, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
|
||||
- status = pNtQuerySemaphore((HANDLE)0xdeadbeef, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
- ok( status == STATUS_INVALID_HANDLE,
|
||||
- "Failed to NtQuerySemaphore, expected STATUS_INVALID_HANDLE, got %08x\n", status );
|
||||
-
|
||||
- len = -1;
|
||||
- memset(&info, 0xcc, sizeof(info));
|
||||
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), &len);
|
||||
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
- ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
|
||||
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
- ok( len == sizeof(info), "got %u\n", len );
|
||||
-
|
||||
- ret = WaitForSingleObject( semaphore, 1000 );
|
||||
- ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
|
||||
-
|
||||
- memset(&info, 0xcc, sizeof(info));
|
||||
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
- ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
|
||||
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
-
|
||||
- prev = 0xdeadbeef;
|
||||
- status = pNtReleaseSemaphore(semaphore, 3, &prev);
|
||||
- ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
|
||||
- ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
|
||||
-
|
||||
- prev = 0xdeadbeef;
|
||||
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
- ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
|
||||
- ok( prev == 0, "NtReleaseSemaphore failed, expected 0, got %d\n", prev );
|
||||
-
|
||||
- prev = 0xdeadbeef;
|
||||
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
- ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
|
||||
- ok( prev == 1, "NtReleaseSemaphore failed, expected 1, got %d\n", prev );
|
||||
-
|
||||
- prev = 0xdeadbeef;
|
||||
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
- ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
|
||||
- ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
|
||||
-
|
||||
- memset(&info, 0xcc, sizeof(info));
|
||||
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
- ok( info.CurrentCount == 2, "expected 2, got %d\n", info.CurrentCount );
|
||||
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
-
|
||||
- NtClose( semaphore );
|
||||
-}
|
||||
-
|
||||
-static void test_wait_on_address(void)
|
||||
-{
|
||||
- DWORD ticks;
|
||||
@ -549,7 +622,7 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
static void test_process(void)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
@@ -2668,13 +2190,7 @@ START_TEST(om)
|
||||
@@ -2668,13 +2113,7 @@ START_TEST(om)
|
||||
pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
|
||||
pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
|
||||
pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
|
||||
@ -563,7 +636,15 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
|
||||
pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
|
||||
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
|
||||
@@ -2695,15 +2211,9 @@ START_TEST(om)
|
||||
@@ -2686,7 +2125,6 @@ START_TEST(om)
|
||||
pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
|
||||
pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
|
||||
pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
|
||||
- pNtQuerySemaphore = (void *)GetProcAddress(hntdll, "NtQuerySemaphore");
|
||||
pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
|
||||
pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer");
|
||||
pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
|
||||
@@ -2695,15 +2133,9 @@ START_TEST(om)
|
||||
pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
|
||||
pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
|
||||
pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
|
||||
@ -579,13 +660,13 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
|
||||
pNtCreateDebugObject = (void *)GetProcAddress(hntdll, "NtCreateDebugObject");
|
||||
pNtGetNextThread = (void *)GetProcAddress(hntdll, "NtGetNextThread");
|
||||
@@ -2716,12 +2226,8 @@ START_TEST(om)
|
||||
@@ -2716,12 +2148,7 @@ START_TEST(om)
|
||||
test_symboliclink();
|
||||
test_query_object();
|
||||
test_type_mismatch();
|
||||
- test_event();
|
||||
- test_mutant();
|
||||
test_semaphore();
|
||||
- test_semaphore();
|
||||
- test_keyed_events();
|
||||
test_null_device();
|
||||
- test_wait_on_address();
|
||||
@ -594,10 +675,10 @@ index 7d9ca47be12..7759736ca1c 100644
|
||||
test_get_next_thread();
|
||||
diff --git a/dlls/ntdll/tests/sync.c b/dlls/ntdll/tests/sync.c
|
||||
new file mode 100644
|
||||
index 00000000000..3f41cdfeedd
|
||||
index 00000000000..3d6b6a3a04d
|
||||
--- /dev/null
|
||||
+++ b/dlls/ntdll/tests/sync.c
|
||||
@@ -0,0 +1,547 @@
|
||||
@@ -0,0 +1,630 @@
|
||||
+/*
|
||||
+ * Unit tests for NT synchronization objects
|
||||
+ *
|
||||
@ -627,17 +708,20 @@ index 00000000000..3f41cdfeedd
|
||||
+#include "wine/test.h"
|
||||
+
|
||||
+static NTSTATUS (WINAPI *pNtClose)( HANDLE );
|
||||
+static NTSTATUS (WINAPI *pNtCreateEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN );
|
||||
+static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN);
|
||||
+static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
|
||||
+static NTSTATUS (WINAPI *pNtCreateMutant)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, BOOLEAN );
|
||||
+static NTSTATUS (WINAPI *pNtCreateSemaphore)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, LONG, LONG );
|
||||
+static NTSTATUS (WINAPI *pNtOpenEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
|
||||
+static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
|
||||
+static NTSTATUS (WINAPI *pNtPulseEvent)( HANDLE, LONG * );
|
||||
+static NTSTATUS (WINAPI *pNtQueryEvent)( HANDLE, EVENT_INFORMATION_CLASS, void *, ULONG, ULONG * );
|
||||
+static NTSTATUS (WINAPI *pNtQueryMutant)( HANDLE, MUTANT_INFORMATION_CLASS, void *, ULONG, ULONG * );
|
||||
+static NTSTATUS (WINAPI *pNtQuerySemaphore)( HANDLE, SEMAPHORE_INFORMATION_CLASS, void *, ULONG, ULONG * );
|
||||
+static NTSTATUS (WINAPI *pNtQuerySystemTime)( LARGE_INTEGER * );
|
||||
+static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
|
||||
+static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * );
|
||||
+static NTSTATUS (WINAPI *pNtReleaseSemaphore)( HANDLE, ULONG, ULONG * );
|
||||
+static NTSTATUS (WINAPI *pNtResetEvent)( HANDLE, LONG * );
|
||||
+static NTSTATUS (WINAPI *pNtSetEvent)( HANDLE, LONG * );
|
||||
+static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
|
||||
@ -652,89 +736,89 @@ index 00000000000..3f41cdfeedd
|
||||
+
|
||||
+static void test_event(void)
|
||||
+{
|
||||
+ HANDLE Event;
|
||||
+ HANDLE Event2;
|
||||
+ HANDLE event;
|
||||
+ HANDLE event2;
|
||||
+ LONG prev_state = 0xdeadbeef;
|
||||
+ NTSTATUS status;
|
||||
+ UNICODE_STRING str;
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ EVENT_BASIC_INFORMATION info;
|
||||
+
|
||||
+ pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\testEvent");
|
||||
+ pRtlInitUnicodeString( &str, L"\\BaseNamedObjects\\testEvent" );
|
||||
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
+
|
||||
+ status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, 2, 0);
|
||||
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, 2, 0);
|
||||
+ ok( status == STATUS_INVALID_PARAMETER, "NtCreateEvent failed %08x\n", status );
|
||||
+
|
||||
+ status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, 0);
|
||||
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, NotificationEvent, 0);
|
||||
+ ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
|
||||
+ ok( info.EventType == NotificationEvent && info.EventState == 0,
|
||||
+ "NtQueryEvent failed, expected 0 0, got %d %d\n", info.EventType, info.EventState );
|
||||
+ pNtClose(Event);
|
||||
+ pNtClose(event);
|
||||
+
|
||||
+ status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, SynchronizationEvent, 0);
|
||||
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, SynchronizationEvent, 0);
|
||||
+ ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
|
||||
+
|
||||
+ status = pNtPulseEvent(Event, &prev_state);
|
||||
+ status = pNtPulseEvent(event, &prev_state);
|
||||
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
|
||||
+ ok( !prev_state, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
|
||||
+ ok( info.EventType == SynchronizationEvent && info.EventState == 0,
|
||||
+ "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
|
||||
+
|
||||
+ status = pNtOpenEvent(&Event2, GENERIC_ALL, &attr);
|
||||
+ status = pNtOpenEvent(&event2, GENERIC_ALL, &attr);
|
||||
+ ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
|
||||
+
|
||||
+ pNtClose(Event);
|
||||
+ Event = Event2;
|
||||
+ pNtClose(event);
|
||||
+ event = event2;
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
|
||||
+ ok( info.EventType == SynchronizationEvent && info.EventState == 0,
|
||||
+ "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
|
||||
+
|
||||
+ status = pNtSetEvent( Event, &prev_state );
|
||||
+ status = pNtSetEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
|
||||
+ ok( !prev_state, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
|
||||
+ ok( info.EventType == SynchronizationEvent && info.EventState == 1,
|
||||
+ "NtQueryEvent failed, expected 1 1, got %d %d\n", info.EventType, info.EventState );
|
||||
+
|
||||
+ status = pNtSetEvent( Event, &prev_state );
|
||||
+ status = pNtSetEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
|
||||
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ status = pNtResetEvent( Event, &prev_state );
|
||||
+ status = pNtResetEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
|
||||
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ status = pNtResetEvent( Event, &prev_state );
|
||||
+ status = pNtResetEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
|
||||
+ ok( !prev_state, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ status = pNtPulseEvent( Event, &prev_state );
|
||||
+ status = pNtPulseEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
|
||||
+ ok( !prev_state, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ status = pNtSetEvent( Event, &prev_state );
|
||||
+ status = pNtSetEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
|
||||
+ ok( !prev_state, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ status = pNtPulseEvent( Event, &prev_state );
|
||||
+ status = pNtPulseEvent( event, &prev_state );
|
||||
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
|
||||
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
|
||||
+
|
||||
+ pNtClose(Event);
|
||||
+ pNtClose(event);
|
||||
+}
|
||||
+
|
||||
+static const WCHAR keyed_nameW[] = L"\\BaseNamedObjects\\WineTestEvent";
|
||||
@ -916,7 +1000,7 @@ index 00000000000..3f41cdfeedd
|
||||
+ ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
|
||||
+
|
||||
+ status = pNtCreateEvent( &event, GENERIC_ALL, &attr, NotificationEvent, FALSE );
|
||||
+ ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH,
|
||||
+ ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* 7+ */,
|
||||
+ "CreateEvent %x\n", status );
|
||||
+
|
||||
+ NtClose( handle );
|
||||
@ -1002,13 +1086,13 @@ index 00000000000..3f41cdfeedd
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseMutant(mutant, &prev);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryRelease failed %08x\n", status );
|
||||
+ ok( prev == -1, "NtQueryRelease failed, expected -1, got %d\n", prev );
|
||||
+ ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
|
||||
+ ok( prev == -1, "NtReleaseMutant failed, expected -1, got %d\n", prev );
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseMutant(mutant, &prev);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQueryRelease failed %08x\n", status );
|
||||
+ ok( prev == 0, "NtQueryRelease failed, expected 0, got %d\n", prev );
|
||||
+ ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
|
||||
+ ok( prev == 0, "NtReleaseMutant failed, expected 0, got %d\n", prev );
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
|
||||
@ -1043,6 +1127,82 @@ index 00000000000..3f41cdfeedd
|
||||
+ NtClose( mutant );
|
||||
+}
|
||||
+
|
||||
+static void test_semaphore(void)
|
||||
+{
|
||||
+ SEMAPHORE_BASIC_INFORMATION info;
|
||||
+ OBJECT_ATTRIBUTES attr;
|
||||
+ UNICODE_STRING str;
|
||||
+ NTSTATUS status;
|
||||
+ HANDLE semaphore;
|
||||
+ ULONG prev;
|
||||
+ ULONG len;
|
||||
+ DWORD ret;
|
||||
+
|
||||
+ pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_semaphore");
|
||||
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
|
||||
+
|
||||
+ status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 2, 1);
|
||||
+ ok( status == STATUS_INVALID_PARAMETER, "Failed to create Semaphore(%08x)\n", status );
|
||||
+ status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 1, 2);
|
||||
+ ok( status == STATUS_SUCCESS, "Failed to create Semaphore(%08x)\n", status );
|
||||
+
|
||||
+ /* bogus */
|
||||
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, 0, NULL);
|
||||
+ ok( status == STATUS_INFO_LENGTH_MISMATCH,
|
||||
+ "Failed to NtQuerySemaphore, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
|
||||
+ status = pNtQuerySemaphore(semaphore, 0x42, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_INVALID_INFO_CLASS,
|
||||
+ "Failed to NtQuerySemaphore, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
|
||||
+ status = pNtQuerySemaphore((HANDLE)0xdeadbeef, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_INVALID_HANDLE,
|
||||
+ "Failed to NtQuerySemaphore, expected STATUS_INVALID_HANDLE, got %08x\n", status );
|
||||
+
|
||||
+ len = -1;
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), &len);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
+ ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
|
||||
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
+ ok( len == sizeof(info), "got %u\n", len );
|
||||
+
|
||||
+ ret = WaitForSingleObject( semaphore, 1000 );
|
||||
+ ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
+ ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
|
||||
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseSemaphore(semaphore, 3, &prev);
|
||||
+ ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
|
||||
+ ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
+ ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
|
||||
+ ok( prev == 0, "NtReleaseSemaphore failed, expected 0, got %d\n", prev );
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
+ ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
|
||||
+ ok( prev == 1, "NtReleaseSemaphore failed, expected 1, got %d\n", prev );
|
||||
+
|
||||
+ prev = 0xdeadbeef;
|
||||
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
|
||||
+ ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
|
||||
+ ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
|
||||
+
|
||||
+ memset(&info, 0xcc, sizeof(info));
|
||||
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
|
||||
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
|
||||
+ ok( info.CurrentCount == 2, "expected 2, got %d\n", info.CurrentCount );
|
||||
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
|
||||
+
|
||||
+ NtClose( semaphore );
|
||||
+}
|
||||
+
|
||||
+static void test_wait_on_address(void)
|
||||
+{
|
||||
+ DWORD ticks;
|
||||
@ -1120,29 +1280,33 @@ index 00000000000..3f41cdfeedd
|
||||
+{
|
||||
+ HMODULE module = GetModuleHandleA("ntdll.dll");
|
||||
+
|
||||
+ pNtClose = (void *)GetProcAddress(module, "NtClose");
|
||||
+ pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
|
||||
+ pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
|
||||
+ pNtCreateMutant = (void *)GetProcAddress(module, "NtCreateMutant");
|
||||
+ pNtOpenEvent = (void *)GetProcAddress(module, "NtOpenEvent");
|
||||
+ pNtOpenKeyedEvent = (void *)GetProcAddress(module, "NtOpenKeyedEvent");
|
||||
+ pNtPulseEvent = (void *)GetProcAddress(module, "NtPulseEvent");
|
||||
+ pNtQueryEvent = (void *)GetProcAddress(module, "NtQueryEvent");
|
||||
+ pNtQueryMutant = (void *)GetProcAddress(module, "NtQueryMutant");
|
||||
+ pNtQuerySystemTime = (void *)GetProcAddress(module, "NtQuerySystemTime");
|
||||
+ pNtReleaseKeyedEvent = (void *)GetProcAddress(module, "NtReleaseKeyedEvent");
|
||||
+ pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
|
||||
+ pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
+ pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
+ pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
+ pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
|
||||
+ pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
|
||||
+ pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
|
||||
+ pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
|
||||
+ pNtClose = (void *)GetProcAddress(module, "NtClose");
|
||||
+ pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
|
||||
+ pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
|
||||
+ pNtCreateMutant = (void *)GetProcAddress(module, "NtCreateMutant");
|
||||
+ pNtCreateSemaphore = (void *)GetProcAddress(module, "NtCreateSemaphore");
|
||||
+ pNtOpenEvent = (void *)GetProcAddress(module, "NtOpenEvent");
|
||||
+ pNtOpenKeyedEvent = (void *)GetProcAddress(module, "NtOpenKeyedEvent");
|
||||
+ pNtPulseEvent = (void *)GetProcAddress(module, "NtPulseEvent");
|
||||
+ pNtQueryEvent = (void *)GetProcAddress(module, "NtQueryEvent");
|
||||
+ pNtQueryMutant = (void *)GetProcAddress(module, "NtQueryMutant");
|
||||
+ pNtQuerySemaphore = (void *)GetProcAddress(module, "NtQuerySemaphore");
|
||||
+ pNtQuerySystemTime = (void *)GetProcAddress(module, "NtQuerySystemTime");
|
||||
+ pNtReleaseKeyedEvent = (void *)GetProcAddress(module, "NtReleaseKeyedEvent");
|
||||
+ pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
|
||||
+ pNtReleaseSemaphore = (void *)GetProcAddress(module, "NtReleaseSemaphore");
|
||||
+ pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
+ pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
+ pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
+ pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
|
||||
+ pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
|
||||
+ pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
|
||||
+ pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
|
||||
+
|
||||
+ test_wait_on_address();
|
||||
+ test_event();
|
||||
+ test_mutant();
|
||||
+ test_semaphore();
|
||||
+ test_keyed_events();
|
||||
+}
|
||||
--
|
||||
|
@ -1,18 +1,18 @@
|
||||
From 2107fb9f59bb2beef3b8c12a2adf9cb2be469036 Mon Sep 17 00:00:00 2001
|
||||
From 2cecfc6394a63db07b92c572d0702cf2a8bf0f31 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Thu, 9 Jan 2020 14:51:05 -0600
|
||||
Subject: [PATCH 02/13] ntdll/tests: Add some tests for Rtl* resources.
|
||||
Subject: [PATCH] ntdll/tests: Add some tests for Rtl* resources.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/sync.c | 202 ++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 183 insertions(+), 19 deletions(-)
|
||||
dlls/ntdll/tests/sync.c | 164 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 164 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/sync.c b/dlls/ntdll/tests/sync.c
|
||||
index 9967a2be257..152cdd1530d 100644
|
||||
index 3d6b6a3a04d..21124dae922 100644
|
||||
--- a/dlls/ntdll/tests/sync.c
|
||||
+++ b/dlls/ntdll/tests/sync.c
|
||||
@@ -41,7 +41,12 @@ static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * );
|
||||
@@ -44,7 +44,12 @@ static NTSTATUS (WINAPI *pNtReleaseSemaphore)( HANDLE, ULONG, ULONG * );
|
||||
static NTSTATUS (WINAPI *pNtResetEvent)( HANDLE, LONG * );
|
||||
static NTSTATUS (WINAPI *pNtSetEvent)( HANDLE, LONG * );
|
||||
static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
|
||||
@ -25,11 +25,11 @@ index 9967a2be257..152cdd1530d 100644
|
||||
static NTSTATUS (WINAPI *pRtlWaitOnAddress)( const void *, const void *, SIZE_T, const LARGE_INTEGER * );
|
||||
static void (WINAPI *pRtlWakeAddressAll)( const void * );
|
||||
static void (WINAPI *pRtlWakeAddressSingle)( const void * );
|
||||
@@ -496,32 +501,191 @@ static void test_wait_on_address(void)
|
||||
@@ -595,6 +600,159 @@ static void test_wait_on_address(void)
|
||||
ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
|
||||
}
|
||||
|
||||
+HANDLE thread_ready, thread_done;
|
||||
+static HANDLE thread_ready, thread_done;
|
||||
+
|
||||
+static DWORD WINAPI resource_shared_thread(void *arg)
|
||||
+{
|
||||
@ -185,57 +185,25 @@ index 9967a2be257..152cdd1530d 100644
|
||||
START_TEST(sync)
|
||||
{
|
||||
HMODULE module = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
- pNtClose = (void *)GetProcAddress(module, "NtClose");
|
||||
- pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
|
||||
- pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
|
||||
- pNtCreateMutant = (void *)GetProcAddress(module, "NtCreateMutant");
|
||||
- pNtOpenEvent = (void *)GetProcAddress(module, "NtOpenEvent");
|
||||
- pNtOpenKeyedEvent = (void *)GetProcAddress(module, "NtOpenKeyedEvent");
|
||||
- pNtPulseEvent = (void *)GetProcAddress(module, "NtPulseEvent");
|
||||
- pNtQueryEvent = (void *)GetProcAddress(module, "NtQueryEvent");
|
||||
- pNtQueryMutant = (void *)GetProcAddress(module, "NtQueryMutant");
|
||||
- pNtQuerySystemTime = (void *)GetProcAddress(module, "NtQuerySystemTime");
|
||||
- pNtReleaseKeyedEvent = (void *)GetProcAddress(module, "NtReleaseKeyedEvent");
|
||||
- pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
|
||||
- pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
- pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
- pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
- pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
|
||||
- pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
|
||||
- pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
|
||||
- pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
|
||||
+ pNtClose = (void *)GetProcAddress(module, "NtClose");
|
||||
+ pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
|
||||
+ pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
|
||||
+ pNtCreateMutant = (void *)GetProcAddress(module, "NtCreateMutant");
|
||||
+ pNtOpenEvent = (void *)GetProcAddress(module, "NtOpenEvent");
|
||||
+ pNtOpenKeyedEvent = (void *)GetProcAddress(module, "NtOpenKeyedEvent");
|
||||
+ pNtPulseEvent = (void *)GetProcAddress(module, "NtPulseEvent");
|
||||
+ pNtQueryEvent = (void *)GetProcAddress(module, "NtQueryEvent");
|
||||
+ pNtQueryMutant = (void *)GetProcAddress(module, "NtQueryMutant");
|
||||
+ pNtQuerySystemTime = (void *)GetProcAddress(module, "NtQuerySystemTime");
|
||||
+ pNtReleaseKeyedEvent = (void *)GetProcAddress(module, "NtReleaseKeyedEvent");
|
||||
+ pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
|
||||
+ pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
+ pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
+ pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
@@ -617,7 +775,12 @@ START_TEST(sync)
|
||||
pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
+ pRtlAcquireResourceExclusive = (void *)GetProcAddress(module, "RtlAcquireResourceExclusive");
|
||||
+ pRtlAcquireResourceShared = (void *)GetProcAddress(module, "RtlAcquireResourceShared");
|
||||
+ pRtlDeleteResource = (void *)GetProcAddress(module, "RtlDeleteResource");
|
||||
+ pRtlInitializeResource = (void *)GetProcAddress(module, "RtlInitializeResource");
|
||||
+ pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
|
||||
pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
|
||||
+ pRtlReleaseResource = (void *)GetProcAddress(module, "RtlReleaseResource");
|
||||
+ pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
|
||||
+ pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
|
||||
+ pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
|
||||
|
||||
test_wait_on_address();
|
||||
test_event();
|
||||
pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
|
||||
pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
|
||||
pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
|
||||
@@ -627,4 +790,5 @@ START_TEST(sync)
|
||||
test_mutant();
|
||||
test_semaphore();
|
||||
test_keyed_events();
|
||||
+ test_resource();
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
2.30.2
|
||||
|
||||
|
@ -0,0 +1,174 @@
|
||||
From b14229169f51d73f36bd5821388a3ba455ee5c99 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Fri, 30 Apr 2021 15:07:04 -0500
|
||||
Subject: [PATCH] ntdll: Implement NtAlertThreadByThreadId and
|
||||
NtWaitForAlertByThreadId.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/ntdll.spec | 2 +
|
||||
dlls/ntdll/unix/sync.c | 93 ++++++++++++++++++++++++++++++++++++++++++
|
||||
include/winternl.h | 2 +
|
||||
3 files changed, 97 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
||||
index a9cf662a29a..c9cd6fb59fd 100644
|
||||
--- a/dlls/ntdll/ntdll.spec
|
||||
+++ b/dlls/ntdll/ntdll.spec
|
||||
@@ -137,6 +137,7 @@
|
||||
@ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
|
||||
@ stdcall -syscall NtAlertResumeThread(long ptr)
|
||||
@ stdcall -syscall NtAlertThread(long)
|
||||
+@ stdcall -syscall NtAlertThreadByThreadId(ptr)
|
||||
@ stdcall -syscall NtAllocateLocallyUniqueId(ptr)
|
||||
# @ stub NtAllocateUserPhysicalPages
|
||||
@ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr)
|
||||
@@ -423,6 +424,7 @@
|
||||
@ stdcall -syscall NtUnmapViewOfSection(long ptr)
|
||||
@ stub NtVdmControl
|
||||
@ stub NtW32Call
|
||||
+@ stdcall -syscall NtWaitForAlertByThreadId(ptr ptr)
|
||||
@ stdcall -syscall NtWaitForDebugEvent(long long ptr ptr)
|
||||
@ stdcall -syscall NtWaitForKeyedEvent(long ptr long ptr)
|
||||
@ stdcall -syscall NtWaitForMultipleObjects(long ptr long long ptr)
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 16635ee42fa..014e5e5d0a7 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -32,6 +32,9 @@
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
+#ifdef HAVE_SYS_MMAN_H
|
||||
+#include <sys/mman.h>
|
||||
+#endif
|
||||
#ifdef HAVE_SYS_SYSCALL_H
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
@@ -81,6 +84,12 @@ static const LARGE_INTEGER zero_timeout;
|
||||
|
||||
static pthread_mutex_t addr_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
+static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ if (!timeout) return "(infinite)";
|
||||
+ return wine_dbgstr_longlong( timeout->QuadPart );
|
||||
+}
|
||||
+
|
||||
/* return a monotonic time counter, in Win32 ticks */
|
||||
static inline ULONGLONG monotonic_counter(void)
|
||||
{
|
||||
@@ -2277,6 +2286,90 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
||||
}
|
||||
|
||||
|
||||
+union tid_alert_entry
|
||||
+{
|
||||
+ HANDLE event;
|
||||
+};
|
||||
+
|
||||
+#define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry))
|
||||
+static union tid_alert_entry *tid_alert_blocks[4096];
|
||||
+
|
||||
+static unsigned int handle_to_index( HANDLE handle, unsigned int *block_idx )
|
||||
+{
|
||||
+ unsigned int idx = (wine_server_obj_handle(handle) >> 2) - 1;
|
||||
+ *block_idx = idx / TID_ALERT_BLOCK_SIZE;
|
||||
+ return idx % TID_ALERT_BLOCK_SIZE;
|
||||
+}
|
||||
+
|
||||
+static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
|
||||
+{
|
||||
+ unsigned int block_idx, idx = handle_to_index( tid, &block_idx );
|
||||
+ union tid_alert_entry *entry;
|
||||
+
|
||||
+ if (block_idx > ARRAY_SIZE(tid_alert_blocks))
|
||||
+ {
|
||||
+ FIXME( "tid %p is too high\n", tid );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!tid_alert_blocks[block_idx])
|
||||
+ {
|
||||
+ static const size_t size = TID_ALERT_BLOCK_SIZE * sizeof(union tid_alert_entry);
|
||||
+ void *ptr = anon_mmap_alloc( size, PROT_READ | PROT_WRITE );
|
||||
+ if (ptr == MAP_FAILED) return NULL;
|
||||
+ if (InterlockedCompareExchangePointer( (void **)&tid_alert_blocks[block_idx], ptr, NULL ))
|
||||
+ munmap( ptr, size ); /* someone beat us to it */
|
||||
+ }
|
||||
+
|
||||
+ entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE];
|
||||
+
|
||||
+ if (!entry->event)
|
||||
+ {
|
||||
+ HANDLE event;
|
||||
+
|
||||
+ if (NtCreateEvent( &event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE ))
|
||||
+ return NULL;
|
||||
+ if (InterlockedCompareExchangePointer( &entry->event, event, NULL ))
|
||||
+ NtClose( event );
|
||||
+ }
|
||||
+
|
||||
+ return entry;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * NtAlertThreadByThreadId (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
+{
|
||||
+ union tid_alert_entry *entry = get_tid_alert_entry( tid );
|
||||
+
|
||||
+ TRACE( "%p\n", tid );
|
||||
+
|
||||
+ if (!entry) return STATUS_INVALID_CID;
|
||||
+
|
||||
+ return NtSetEvent( entry->event, NULL );
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * NtWaitForAlertByThreadId (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread );
|
||||
+ NTSTATUS status;
|
||||
+
|
||||
+ TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
|
||||
+
|
||||
+ if (!entry) return STATUS_INVALID_CID;
|
||||
+
|
||||
+ status = NtWaitForSingleObject( entry->event, FALSE, timeout );
|
||||
+ if (!status) return STATUS_ALERTED;
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+
|
||||
#ifdef __linux__
|
||||
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index 69d0e32f1d4..a6c22a5711d 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -3639,6 +3639,7 @@ NTSYSAPI NTSTATUS WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG
|
||||
NTSYSAPI NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle);
|
||||
+NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG);
|
||||
@@ -3876,6 +3877,7 @@ NTSYSAPI NTSTATUS WINAPI NtUnlockFile(HANDLE,PIO_STATUS_BLOCK,PLARGE_INTEGER,PL
|
||||
NTSYSAPI NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
|
||||
NTSYSAPI NTSTATUS WINAPI NtVdmControl(ULONG,PVOID);
|
||||
+NTSYSAPI NTSTATUS WINAPI NtWaitForAlertByThreadId(const void*,const LARGE_INTEGER*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForDebugEvent(HANDLE,BOOLEAN,LARGE_INTEGER*,DBGUI_WAIT_STATE_CHANGE*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE,const void*,BOOLEAN,const LARGE_INTEGER*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 5ac57c442cc9ce10ee8b8e0e82d3e3c199bd3862 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 22:56:03 -0500
|
||||
Subject: [PATCH] ntdll: Use a separate mutex to lock the TEB list.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/virtual.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index f3e6b612b93..f0cec5e1347 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -175,6 +175,7 @@ static void *teb_block;
|
||||
static void **next_free_teb;
|
||||
static int teb_block_pos;
|
||||
static struct list teb_list = LIST_INIT( teb_list );
|
||||
+static pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
#define ROUND_ADDR(addr,mask) ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
||||
#define ROUND_SIZE(addr,size) (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
|
||||
@@ -2880,7 +2881,9 @@ static TEB *init_teb( void *ptr, PEB *peb )
|
||||
thread_data->reply_fd = -1;
|
||||
thread_data->wait_fd[0] = -1;
|
||||
thread_data->wait_fd[1] = -1;
|
||||
+ pthread_rwlock_wrlock( &teb_list_lock );
|
||||
list_add_head( &teb_list, &thread_data->entry );
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
return teb;
|
||||
}
|
||||
|
||||
@@ -2997,7 +3000,9 @@ void virtual_free_teb( TEB *teb )
|
||||
}
|
||||
|
||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
+ pthread_rwlock_wrlock( &teb_list_lock );
|
||||
list_remove( &thread_data->entry );
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
if (!is_win64) ptr = (char *)ptr - teb_offset;
|
||||
*(void **)ptr = next_free_teb;
|
||||
next_free_teb = ptr;
|
||||
@@ -3011,17 +3016,16 @@ void virtual_free_teb( TEB *teb )
|
||||
NTSTATUS virtual_clear_tls_index( ULONG index )
|
||||
{
|
||||
struct ntdll_thread_data *thread_data;
|
||||
- sigset_t sigset;
|
||||
|
||||
if (index < TLS_MINIMUM_AVAILABLE)
|
||||
{
|
||||
- server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
+ pthread_rwlock_rdlock( &teb_list_lock );
|
||||
LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
|
||||
{
|
||||
TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
|
||||
teb->TlsSlots[index] = 0;
|
||||
}
|
||||
- server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3029,13 +3033,13 @@ NTSTATUS virtual_clear_tls_index( ULONG index )
|
||||
if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
- server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
+ pthread_rwlock_rdlock( &teb_list_lock );
|
||||
LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
|
||||
{
|
||||
TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
|
||||
if (teb->TlsExpansionSlots) teb->TlsExpansionSlots[index] = 0;
|
||||
}
|
||||
- server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,172 +0,0 @@
|
||||
From 94c6132d79ee02079fc952e33cccf0d1f456a1ec Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:00:16 -0500
|
||||
Subject: [PATCH] ntdll: Implement NtAlertThreadByThreadId() and
|
||||
NtWaitForAlertByThreadId().
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/ntdll.spec | 2 ++
|
||||
dlls/ntdll/unix/sync.c | 45 ++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/thread.c | 2 ++
|
||||
dlls/ntdll/unix/unix_private.h | 3 +++
|
||||
dlls/ntdll/unix/virtual.c | 5 ++--
|
||||
include/winternl.h | 2 ++
|
||||
6 files changed, 57 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
|
||||
index ac7365a84b6..91959e19149 100644
|
||||
--- a/dlls/ntdll/ntdll.spec
|
||||
+++ b/dlls/ntdll/ntdll.spec
|
||||
@@ -137,6 +137,7 @@
|
||||
@ stdcall -syscall NtAdjustPrivilegesToken(long long ptr long ptr ptr)
|
||||
@ stdcall -syscall NtAlertResumeThread(long ptr)
|
||||
@ stdcall -syscall NtAlertThread(long)
|
||||
+@ stdcall -syscall NtAlertThreadByThreadId(ptr)
|
||||
@ stdcall -syscall NtAllocateLocallyUniqueId(ptr)
|
||||
# @ stub NtAllocateUserPhysicalPages
|
||||
@ stdcall -syscall NtAllocateUuids(ptr ptr ptr ptr)
|
||||
@@ -423,6 +424,7 @@
|
||||
@ stub NtVdmControl
|
||||
@ stub NtW32Call
|
||||
@ stdcall -syscall NtWaitForDebugEvent(long long ptr ptr)
|
||||
+@ stdcall -syscall NtWaitForAlertByThreadId(ptr ptr)
|
||||
@ stdcall -syscall NtWaitForKeyedEvent(long ptr long ptr)
|
||||
@ stdcall -syscall NtWaitForMultipleObjects(long ptr long long ptr)
|
||||
@ stub NtWaitForProcessMutant
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 16635ee42fa..7e19fab1e97 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -81,6 +81,12 @@ static const LARGE_INTEGER zero_timeout;
|
||||
|
||||
static pthread_mutex_t addr_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
+static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ if (!timeout) return "(infinite)";
|
||||
+ return wine_dbgstr_longlong( timeout->QuadPart );
|
||||
+}
|
||||
+
|
||||
/* return a monotonic time counter, in Win32 ticks */
|
||||
static inline ULONGLONG monotonic_counter(void)
|
||||
{
|
||||
@@ -2277,6 +2283,45 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
||||
}
|
||||
|
||||
|
||||
+/***********************************************************************
|
||||
+ * NtAlertThreadByThreadId (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
+{
|
||||
+ struct ntdll_thread_data *thread_data;
|
||||
+
|
||||
+ TRACE( "%p\n", tid );
|
||||
+
|
||||
+ pthread_rwlock_rdlock( &teb_list_lock );
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY( thread_data, &teb_list, struct ntdll_thread_data, entry )
|
||||
+ {
|
||||
+ TEB *teb = CONTAINING_RECORD( thread_data, TEB, GdiTebBatch );
|
||||
+
|
||||
+ if (teb->ClientId.UniqueThread == tid)
|
||||
+ {
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
+ NtSetEvent( thread_data->tid_alert_event, NULL );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pthread_rwlock_unlock( &teb_list_lock );
|
||||
+ return STATUS_INVALID_CID;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * NtWaitForAlertByThreadId (NTDLL.@)
|
||||
+ */
|
||||
+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
|
||||
+
|
||||
+ return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
|
||||
+}
|
||||
+
|
||||
+
|
||||
#ifdef __linux__
|
||||
|
||||
NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
|
||||
index 00d29ae706b..87f5a97131e 100644
|
||||
--- a/dlls/ntdll/unix/thread.c
|
||||
+++ b/dlls/ntdll/unix/thread.c
|
||||
@@ -252,6 +252,8 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
||||
thread_data->start = start;
|
||||
thread_data->param = param;
|
||||
|
||||
+ NtCreateEvent( &thread_data->tid_alert_event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE );
|
||||
+
|
||||
pthread_attr_init( &pthread_attr );
|
||||
pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
|
||||
(char *)teb->Tib.StackBase + extra_stack - (char *)teb->DeallocationStack );
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index b8b6619c0a9..ae178fadd8b 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -58,6 +58,7 @@ struct ntdll_thread_data
|
||||
struct list entry; /* entry in TEB list */
|
||||
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
|
||||
void *param; /* thread entry point parameter */
|
||||
+ HANDLE tid_alert_event; /* event for thread-id alerts */
|
||||
};
|
||||
|
||||
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
|
||||
@@ -105,6 +106,8 @@ extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||
|
||||
+extern struct list teb_list DECLSPEC_HIDDEN;
|
||||
+extern pthread_rwlock_t teb_list_lock DECLSPEC_HIDDEN;
|
||||
extern const char *home_dir DECLSPEC_HIDDEN;
|
||||
extern const char *data_dir DECLSPEC_HIDDEN;
|
||||
extern const char *build_dir DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
|
||||
index d1d00b91345..3e3c9b5f00e 100644
|
||||
--- a/dlls/ntdll/unix/virtual.c
|
||||
+++ b/dlls/ntdll/unix/virtual.c
|
||||
@@ -162,8 +162,9 @@ struct _KUSER_SHARED_DATA *user_shared_data = (void *)0x7ffe0000;
|
||||
static void *teb_block;
|
||||
static void **next_free_teb;
|
||||
static int teb_block_pos;
|
||||
-static struct list teb_list = LIST_INIT( teb_list );
|
||||
-static pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
+
|
||||
+struct list teb_list = LIST_INIT( teb_list );
|
||||
+pthread_rwlock_t teb_list_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
#define ROUND_ADDR(addr,mask) ((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
||||
#define ROUND_SIZE(addr,size) (((SIZE_T)(size) + ((UINT_PTR)(addr) & page_mask) + page_mask) & ~page_mask)
|
||||
diff --git a/include/winternl.h b/include/winternl.h
|
||||
index f0ab223ef2e..9a5a1b541b7 100644
|
||||
--- a/include/winternl.h
|
||||
+++ b/include/winternl.h
|
||||
@@ -3229,6 +3229,7 @@ NTSYSAPI NTSTATUS WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG
|
||||
NTSYSAPI NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAlertResumeThread(HANDLE,PULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAlertThread(HANDLE ThreadHandle);
|
||||
+NTSYSAPI NTSTATUS WINAPI NtAlertThreadByThreadId(HANDLE);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateLocallyUniqueId(PLUID lpLuid);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateUuids(PULARGE_INTEGER,PULONG,PULONG,PUCHAR);
|
||||
NTSYSAPI NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,ULONG_PTR,SIZE_T*,ULONG,ULONG);
|
||||
@@ -3467,6 +3468,7 @@ NTSYSAPI NTSTATUS WINAPI NtUnlockVirtualMemory(HANDLE,PVOID*,SIZE_T*,ULONG);
|
||||
NTSYSAPI NTSTATUS WINAPI NtUnmapViewOfSection(HANDLE,PVOID);
|
||||
NTSYSAPI NTSTATUS WINAPI NtVdmControl(ULONG,PVOID);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForDebugEvent(HANDLE,BOOLEAN,LARGE_INTEGER*,DBGUI_WAIT_STATE_CHANGE*);
|
||||
+NTSYSAPI NTSTATUS WINAPI NtWaitForAlertByThreadId(const void*,const LARGE_INTEGER*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE,const void*,BOOLEAN,const LARGE_INTEGER*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForSingleObject(HANDLE,BOOLEAN,const LARGE_INTEGER*);
|
||||
NTSYSAPI NTSTATUS WINAPI NtWaitForMultipleObjects(ULONG,const HANDLE*,BOOLEAN,BOOLEAN,const LARGE_INTEGER*);
|
||||
--
|
||||
2.20.1
|
||||
|
@ -1,15 +1,15 @@
|
||||
From a993ebacecfcaa3370b7661baef6767d987ffed2 Mon Sep 17 00:00:00 2001
|
||||
From 775dcb8ca2ee8f16de16193570995dfe306be24d Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:01:25 -0500
|
||||
Subject: [PATCH] ntdll/tests: Add basic tests for thread-id alert functions.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/tests/sync.c | 59 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 59 insertions(+)
|
||||
dlls/ntdll/tests/sync.c | 95 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 95 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/tests/sync.c b/dlls/ntdll/tests/sync.c
|
||||
index 2ebdbd1b6f5..0c04c450948 100644
|
||||
index 21124dae922..be49405d8de 100644
|
||||
--- a/dlls/ntdll/tests/sync.c
|
||||
+++ b/dlls/ntdll/tests/sync.c
|
||||
@@ -26,6 +26,7 @@
|
||||
@ -18,27 +18,42 @@ index 2ebdbd1b6f5..0c04c450948 100644
|
||||
|
||||
+static NTSTATUS (WINAPI *pNtAlertThreadByThreadId)( HANDLE );
|
||||
static NTSTATUS (WINAPI *pNtClose)( HANDLE );
|
||||
static NTSTATUS (WINAPI *pNtCreateEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN );
|
||||
static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN);
|
||||
static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
|
||||
@@ -40,6 +41,7 @@ static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, c
|
||||
static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * );
|
||||
@@ -43,6 +44,7 @@ static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * );
|
||||
static NTSTATUS (WINAPI *pNtReleaseSemaphore)( HANDLE, ULONG, ULONG * );
|
||||
static NTSTATUS (WINAPI *pNtResetEvent)( HANDLE, LONG * );
|
||||
static NTSTATUS (WINAPI *pNtSetEvent)( HANDLE, LONG * );
|
||||
+static NTSTATUS (WINAPI *pNtWaitForAlertByThreadId)( void *, const LARGE_INTEGER * );
|
||||
static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
|
||||
static BOOLEAN (WINAPI *pRtlAcquireResourceExclusive)( RTL_RWLOCK *, BOOLEAN );
|
||||
static BOOLEAN (WINAPI *pRtlAcquireResourceShared)( RTL_RWLOCK *, BOOLEAN );
|
||||
@@ -674,10 +676,65 @@ static void test_resource(void)
|
||||
@@ -753,10 +755,101 @@ static void test_resource(void)
|
||||
pRtlDeleteResource(&resource);
|
||||
}
|
||||
|
||||
+static void test_thread_id_alert( char **argv )
|
||||
+static DWORD WINAPI tid_alert_thread( void *arg )
|
||||
+{
|
||||
+ static const LARGE_INTEGER zero;
|
||||
+ NTSTATUS ret;
|
||||
+
|
||||
+ ret = pNtAlertThreadByThreadId( arg );
|
||||
+ ok(!ret, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, NULL );
|
||||
+ ok(ret == STATUS_ALERTED, "got %#x\n", ret);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void test_tid_alert( char **argv )
|
||||
+{
|
||||
+ LARGE_INTEGER timeout = {0};
|
||||
+ char cmdline[MAX_PATH];
|
||||
+ STARTUPINFOA si = {0};
|
||||
+ PROCESS_INFORMATION pi;
|
||||
+ HANDLE thread;
|
||||
+ NTSTATUS ret;
|
||||
+ DWORD tid;
|
||||
+
|
||||
+ if (!pNtWaitForAlertByThreadId)
|
||||
+ {
|
||||
@ -46,7 +61,7 @@ index 2ebdbd1b6f5..0c04c450948 100644
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &zero );
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout );
|
||||
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = pNtAlertThreadByThreadId( 0 );
|
||||
@ -61,15 +76,36 @@ index 2ebdbd1b6f5..0c04c450948 100644
|
||||
+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)GetCurrentThreadId() );
|
||||
+ ok(!ret, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &zero );
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout );
|
||||
+ ok(ret == STATUS_ALERTED, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &zero );
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout );
|
||||
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x321, &zero );
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x321, &timeout );
|
||||
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
|
||||
+
|
||||
+ thread = CreateThread( NULL, 0, tid_alert_thread, (HANDLE)(DWORD_PTR)GetCurrentThreadId(), 0, &tid );
|
||||
+ timeout.QuadPart = -1000 * 10000;
|
||||
+ ret = pNtWaitForAlertByThreadId( (void *)0x123, &timeout );
|
||||
+ ok(ret == STATUS_ALERTED, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = WaitForSingleObject( thread, 100 );
|
||||
+ ok(ret == WAIT_TIMEOUT, "got %d\n", ret);
|
||||
+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid );
|
||||
+ ok(!ret, "got %#x\n", ret);
|
||||
+
|
||||
+ ret = WaitForSingleObject( thread, 1000 );
|
||||
+ ok(!ret, "got %d\n", ret);
|
||||
+
|
||||
+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid );
|
||||
+ ok(!ret, "got %#x\n", ret);
|
||||
+
|
||||
+ CloseHandle(thread);
|
||||
+
|
||||
+ ret = pNtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid );
|
||||
+ todo_wine ok(ret == STATUS_INVALID_CID, "got %#x\n", ret);
|
||||
+
|
||||
+ sprintf( cmdline, "%s %s subprocess", argv[0], argv[1] );
|
||||
+ ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
|
||||
+ ok(ret, "failed to create process, error %u\n", GetLastError());
|
||||
@ -85,29 +121,29 @@ index 2ebdbd1b6f5..0c04c450948 100644
|
||||
HMODULE module = GetModuleHandleA("ntdll.dll");
|
||||
+ char **argv;
|
||||
+ int argc;
|
||||
+
|
||||
|
||||
+ argc = winetest_get_mainargs( &argv );
|
||||
+
|
||||
+ if (argc > 2) return;
|
||||
|
||||
+
|
||||
+ pNtAlertThreadByThreadId = (void *)GetProcAddress(module, "NtAlertThreadByThreadId");
|
||||
pNtClose = (void *)GetProcAddress(module, "NtClose");
|
||||
pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
|
||||
pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
|
||||
@@ -692,6 +749,7 @@ START_TEST(sync)
|
||||
pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
|
||||
@@ -774,6 +867,7 @@ START_TEST(sync)
|
||||
pNtReleaseSemaphore = (void *)GetProcAddress(module, "NtReleaseSemaphore");
|
||||
pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
|
||||
pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
|
||||
+ pNtWaitForAlertByThreadId = (void *)GetProcAddress(module, "NtWaitForAlertByThreadId");
|
||||
pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
|
||||
pRtlAcquireResourceExclusive = (void *)GetProcAddress(module, "RtlAcquireResourceExclusive");
|
||||
pRtlAcquireResourceShared = (void *)GetProcAddress(module, "RtlAcquireResourceShared");
|
||||
@@ -708,4 +766,5 @@ START_TEST(sync)
|
||||
test_mutant();
|
||||
@@ -791,4 +885,5 @@ START_TEST(sync)
|
||||
test_semaphore();
|
||||
test_keyed_events();
|
||||
test_resource();
|
||||
+ test_thread_id_alert( argv );
|
||||
+ test_tid_alert( argv );
|
||||
}
|
||||
--
|
||||
2.29.2
|
||||
2.30.2
|
||||
|
@ -1,39 +1,58 @@
|
||||
From c6423d645d002113fce7b3194023ec507549c39a Mon Sep 17 00:00:00 2001
|
||||
From f910f81d3c8f3c01f7582738e61071ae7a24dfea Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:02:56 -0500
|
||||
Subject: [PATCH 06/13] ntdll: Implement thread-id alerts on top of futexes if
|
||||
possible.
|
||||
Date: Fri, 30 Apr 2021 16:35:13 -0500
|
||||
Subject: [PATCH] ntdll: Implement thread-ID alerts using futexes if possible.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/sync.c | 65 ++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/unix_private.h | 3 ++
|
||||
2 files changed, 68 insertions(+)
|
||||
dlls/ntdll/unix/sync.c | 76 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 76 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 2ed164368b9..3fd3545bbbb 100644
|
||||
index 014e5e5d0a7..058262ac0ad 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2143,6 +2143,15 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
if (teb->ClientId.UniqueThread == tid)
|
||||
{
|
||||
pthread_rwlock_unlock( &teb_list_lock );
|
||||
@@ -2289,6 +2289,9 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
||||
union tid_alert_entry
|
||||
{
|
||||
HANDLE event;
|
||||
+#ifdef __linux__
|
||||
+ if (use_futexes())
|
||||
+ {
|
||||
+ int *futex = &thread_data->tid_alert_futex;
|
||||
+ if (!InterlockedExchange( futex, 1 ))
|
||||
+ futex_wake( futex, 1 );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+ int futex;
|
||||
+#endif
|
||||
NtSetEvent( thread_data->tid_alert_event, NULL );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -2153,6 +2162,28 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
};
|
||||
|
||||
#define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry))
|
||||
@@ -2323,6 +2326,11 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
|
||||
|
||||
entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE];
|
||||
|
||||
+#ifdef __linux__
|
||||
+ if (use_futexes())
|
||||
+ return entry;
|
||||
+#endif
|
||||
+
|
||||
if (!entry->event)
|
||||
{
|
||||
HANDLE event;
|
||||
@@ -2348,10 +2356,43 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
|
||||
if (!entry) return STATUS_INVALID_CID;
|
||||
|
||||
+#ifdef __linux__
|
||||
+ if (use_futexes())
|
||||
+ {
|
||||
+ int *futex = &entry->futex;
|
||||
+ if (!InterlockedExchange( futex, 1 ))
|
||||
+ futex_wake( futex, 1 );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return NtSetEvent( entry->event, NULL );
|
||||
}
|
||||
|
||||
|
||||
+#ifdef __linux__
|
||||
+static LONGLONG get_absolute_timeout( const LARGE_INTEGER *timeout )
|
||||
+{
|
||||
+ LARGE_INTEGER now;
|
||||
@ -43,7 +62,6 @@ index 2ed164368b9..3fd3545bbbb 100644
|
||||
+ return now.QuadPart - timeout->QuadPart;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static LONGLONG update_timeout( ULONGLONG end )
|
||||
+{
|
||||
+ LARGE_INTEGER now;
|
||||
@ -54,19 +72,20 @@ index 2ed164368b9..3fd3545bbbb 100644
|
||||
+ if (timeleft < 0) timeleft = 0;
|
||||
+ return timeleft;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
/***********************************************************************
|
||||
* NtWaitForAlertByThreadId (NTDLL.@)
|
||||
*/
|
||||
@@ -2160,6 +2191,40 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
{
|
||||
TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
|
||||
@@ -2364,6 +2405,41 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
|
||||
if (!entry) return STATUS_INVALID_CID;
|
||||
|
||||
+#ifdef __linux__
|
||||
+ if (use_futexes())
|
||||
+ {
|
||||
+ int *futex = &ntdll_get_thread_data()->tid_alert_futex;
|
||||
+ int *futex = &entry->futex;
|
||||
+ ULONGLONG end;
|
||||
+ int ret;
|
||||
+
|
||||
@ -97,23 +116,10 @@ index 2ed164368b9..3fd3545bbbb 100644
|
||||
+ return STATUS_ALERTED;
|
||||
+ }
|
||||
+#endif
|
||||
return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
|
||||
}
|
||||
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 9ae7cba34a7..327e12519a0 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -57,6 +57,9 @@ struct ntdll_thread_data
|
||||
struct list entry; /* entry in TEB list */
|
||||
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
|
||||
void *param; /* thread entry point parameter */
|
||||
+#ifdef __linux__
|
||||
+ int tid_alert_futex; /* futex for thread-id alerts */
|
||||
+#endif
|
||||
HANDLE tid_alert_event; /* event for thread-id alerts */
|
||||
};
|
||||
|
||||
+
|
||||
status = NtWaitForSingleObject( entry->event, FALSE, timeout );
|
||||
if (!status) return STATUS_ALERTED;
|
||||
return status;
|
||||
--
|
||||
2.29.2
|
||||
2.30.2
|
||||
|
@ -0,0 +1,131 @@
|
||||
From adc9f55669d56782cdc7336d2f10f4aa6ac16355 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Fri, 30 Apr 2021 16:43:08 -0500
|
||||
Subject: [PATCH] ntdll: Implement thread-ID alerts using Mach semaphores on
|
||||
Mac.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/sync.c | 60 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 60 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 058262ac0ad..4fa890e5acc 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2288,10 +2288,14 @@ NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS cl
|
||||
|
||||
union tid_alert_entry
|
||||
{
|
||||
+#ifdef __APPLE__
|
||||
+ semaphore_t sem;
|
||||
+#else
|
||||
HANDLE event;
|
||||
#ifdef __linux__
|
||||
int futex;
|
||||
#endif
|
||||
+#endif
|
||||
};
|
||||
|
||||
#define TID_ALERT_BLOCK_SIZE (65536 / sizeof(union tid_alert_entry))
|
||||
@@ -2326,6 +2330,17 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
|
||||
|
||||
entry = &tid_alert_blocks[block_idx][idx % TID_ALERT_BLOCK_SIZE];
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ if (!entry->sem)
|
||||
+ {
|
||||
+ semaphore_t sem;
|
||||
+
|
||||
+ if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 ))
|
||||
+ return NULL;
|
||||
+ if (InterlockedCompareExchangePointer( (void **)&entry->sem, sem, NULL ))
|
||||
+ semaphore_destroy( sem );
|
||||
+ }
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
if (use_futexes())
|
||||
return entry;
|
||||
@@ -2340,6 +2355,7 @@ static union tid_alert_entry *get_tid_alert_entry( HANDLE tid )
|
||||
if (InterlockedCompareExchangePointer( &entry->event, event, NULL ))
|
||||
NtClose( event );
|
||||
}
|
||||
+#endif
|
||||
|
||||
return entry;
|
||||
}
|
||||
@@ -2356,6 +2372,10 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
|
||||
if (!entry) return STATUS_INVALID_CID;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ semaphore_signal( entry->sem );
|
||||
+ return STATUS_SUCCESS;
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
if (use_futexes())
|
||||
{
|
||||
@@ -2367,6 +2387,7 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
#endif
|
||||
|
||||
return NtSetEvent( entry->event, NULL );
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -2405,6 +2426,44 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
|
||||
if (!entry) return STATUS_INVALID_CID;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ {
|
||||
+ semaphore_t sem = entry->sem;
|
||||
+ ULONGLONG end;
|
||||
+ kern_return_t ret;
|
||||
+
|
||||
+ if (timeout)
|
||||
+ {
|
||||
+ if (timeout->QuadPart == TIMEOUT_INFINITE)
|
||||
+ timeout = NULL;
|
||||
+ else
|
||||
+ end = get_absolute_timeout( timeout );
|
||||
+ }
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ if (timeout)
|
||||
+ {
|
||||
+ LONGLONG timeleft = update_timeout( end );
|
||||
+ mach_timespec_t timespec;
|
||||
+
|
||||
+ timespec.tv_sec = timeleft / (ULONGLONG)TICKSPERSEC;
|
||||
+ timespec.tv_nsec = (timeleft % TICKSPERSEC) * 100;
|
||||
+ ret = semaphore_timedwait( sem, timespec );
|
||||
+ }
|
||||
+ else
|
||||
+ ret = semaphore_wait( sem );
|
||||
+
|
||||
+ switch (ret)
|
||||
+ {
|
||||
+ case KERN_SUCCESS: return STATUS_ALERTED;
|
||||
+ case KERN_ABORTED: continue;
|
||||
+ case KERN_OPERATION_TIMED_OUT: return STATUS_TIMEOUT;
|
||||
+ default: return STATUS_INVALID_HANDLE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
if (use_futexes())
|
||||
{
|
||||
@@ -2443,6 +2502,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
status = NtWaitForSingleObject( entry->event, FALSE, timeout );
|
||||
if (!status) return STATUS_ALERTED;
|
||||
return status;
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,139 +0,0 @@
|
||||
From 32902deea99f78645f82f283f5cde453607cec1d Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:03:34 -0500
|
||||
Subject: [PATCH] ntdll: Implement thread-id alerts on top of Mach semaphores
|
||||
on Mac.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/sync.c | 44 ++++++++++++++++++++++++++++++++++
|
||||
dlls/ntdll/unix/thread.c | 4 ++++
|
||||
dlls/ntdll/unix/unix_private.h | 9 +++++++
|
||||
3 files changed, 57 insertions(+)
|
||||
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index f4f87ba5642..7d6423083e1 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2301,6 +2301,10 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
if (teb->ClientId.UniqueThread == tid)
|
||||
{
|
||||
pthread_rwlock_unlock( &teb_list_lock );
|
||||
+#ifdef __APPLE__
|
||||
+ semaphore_signal( thread_data->tid_alert_sem );
|
||||
+ return STATUS_SUCCESS;
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
if (use_futexes())
|
||||
{
|
||||
@@ -2312,6 +2316,7 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid )
|
||||
#endif
|
||||
NtSetEvent( thread_data->tid_alert_event, NULL );
|
||||
return STATUS_SUCCESS;
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2349,6 +2354,44 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
{
|
||||
TRACE( "%p %s\n", address, debugstr_timeout( timeout ) );
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ {
|
||||
+ semaphore_t sem = ntdll_get_thread_data()->tid_alert_sem;
|
||||
+ ULONGLONG end;
|
||||
+ kern_return_t ret;
|
||||
+
|
||||
+ if (timeout)
|
||||
+ {
|
||||
+ if (timeout->QuadPart == TIMEOUT_INFINITE)
|
||||
+ timeout = NULL;
|
||||
+ else
|
||||
+ end = get_absolute_timeout( timeout );
|
||||
+ }
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ if (timeout)
|
||||
+ {
|
||||
+ LONGLONG timeleft = update_timeout( end );
|
||||
+ mach_timespec_t timespec;
|
||||
+
|
||||
+ timespec.tv_sec = timeleft / (ULONGLONG)TICKSPERSEC;
|
||||
+ timespec.tv_nsec = (timeleft % TICKSPERSEC) * 100;
|
||||
+ ret = semaphore_timedwait( sem, timespec );
|
||||
+ }
|
||||
+ else
|
||||
+ ret = semaphore_wait( sem );
|
||||
+
|
||||
+ switch (ret)
|
||||
+ {
|
||||
+ case KERN_SUCCESS: return STATUS_ALERTED;
|
||||
+ case KERN_ABORTED: continue;
|
||||
+ case KERN_OPERATION_TIMED_OUT: return STATUS_TIMEOUT;
|
||||
+ default: return STATUS_INVALID_HANDLE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
if (use_futexes())
|
||||
{
|
||||
@@ -2384,6 +2427,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
}
|
||||
#endif
|
||||
return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
||||
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
|
||||
index bfcd7bf04a7..9b3c9a91abc 100644
|
||||
--- a/dlls/ntdll/unix/thread.c
|
||||
+++ b/dlls/ntdll/unix/thread.c
|
||||
@@ -262,7 +262,11 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT
|
||||
thread_data->start = start;
|
||||
thread_data->param = param;
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+ semaphore_create( mach_task_self(), &thread_data->tid_alert_sem, SYNC_POLICY_FIFO, 0 );
|
||||
+#else
|
||||
NtCreateEvent( &thread_data->tid_alert_event, EVENT_ALL_ACCESS, NULL, SynchronizationEvent, FALSE );
|
||||
+#endif
|
||||
|
||||
pthread_attr_init( &pthread_attr );
|
||||
pthread_attr_setstack( &pthread_attr, teb->DeallocationStack,
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 4c38ed8ef29..3d629de09b2 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -27,6 +27,11 @@
|
||||
#include "wine/server.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
+#ifdef __APPLE__
|
||||
+# include <mach/mach.h>
|
||||
+# include <mach/semaphore.h>
|
||||
+#endif
|
||||
+
|
||||
#ifdef __i386__
|
||||
static const WORD current_machine = IMAGE_FILE_MACHINE_I386;
|
||||
#elif defined(__x86_64__)
|
||||
@@ -60,10 +65,14 @@ struct ntdll_thread_data
|
||||
struct list entry; /* entry in TEB list */
|
||||
PRTL_THREAD_START_ROUTINE start; /* thread entry point */
|
||||
void *param; /* thread entry point parameter */
|
||||
+#ifdef __APPLE__
|
||||
+ semaphore_t tid_alert_sem; /* Mach semaphore for thread-id alerts */
|
||||
+#else
|
||||
#ifdef __linux__
|
||||
int tid_alert_futex; /* futex for thread-id alerts */
|
||||
#endif
|
||||
HANDLE tid_alert_event; /* event for thread-id alerts */
|
||||
+#endif
|
||||
};
|
||||
|
||||
C_ASSERT( sizeof(struct ntdll_thread_data) <= sizeof(((TEB *)0)->GdiTebBatch) );
|
||||
--
|
||||
2.30.2
|
||||
|
@ -1,33 +1,18 @@
|
||||
From b41fc553cecc9ba5c81cda41bb85e2ee1937586e Mon Sep 17 00:00:00 2001
|
||||
From 4c99070bbd7dd897a6e27bd94e8f50206b3ad49c Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 2 Nov 2020 20:24:07 -0600
|
||||
Subject: [PATCH] ntdll: Reimplement Win32 futexes on top of thread-ID alerts.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/ntdll_misc.h | 2 +
|
||||
dlls/ntdll/sync.c | 185 ++++++++++++++++++++++++++++++++++++++-
|
||||
dlls/ntdll/thread.c | 2 +
|
||||
dlls/ntdll/sync.c | 158 +++++++++++++++++++++++++++++++++++++-
|
||||
dlls/ntdll/unix/loader.c | 3 -
|
||||
dlls/ntdll/unix/sync.c | 162 ----------------------------------
|
||||
dlls/ntdll/unix/sync.c | 162 ---------------------------------------
|
||||
dlls/ntdll/unixlib.h | 6 +-
|
||||
6 files changed, 187 insertions(+), 173 deletions(-)
|
||||
4 files changed, 156 insertions(+), 173 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
|
||||
index b8f9dc28e63..eab3b5e5248 100644
|
||||
--- a/dlls/ntdll/ntdll_misc.h
|
||||
+++ b/dlls/ntdll/ntdll_misc.h
|
||||
@@ -85,6 +85,8 @@ extern const struct unix_funcs *unix_funcs DECLSPEC_HIDDEN;
|
||||
|
||||
extern struct _KUSER_SHARED_DATA *user_shared_data DECLSPEC_HIDDEN;
|
||||
|
||||
+extern void addr_wait_free_entry(void) DECLSPEC_HIDDEN;
|
||||
+
|
||||
extern int CDECL NTDLL__vsnprintf( char *str, SIZE_T len, const char *format, __ms_va_list args ) DECLSPEC_HIDDEN;
|
||||
extern int CDECL NTDLL__vsnwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, __ms_va_list args ) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index f1263ae33fd..d652f55b630 100644
|
||||
index f1263ae33fd..348f260c3b0 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -36,6 +36,13 @@
|
||||
@ -44,75 +29,48 @@ index f1263ae33fd..d652f55b630 100644
|
||||
|
||||
/******************************************************************
|
||||
* RtlRunOnceInitialize (NTDLL.@)
|
||||
@@ -530,13 +537,143 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
@@ -530,13 +537,111 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/* The following functions define a lock-free array mapping thread IDs to
|
||||
+ * values, which can be grown but not shrunk. We do this by allocating one slice
|
||||
+ * of the array at a time, and storing a pointer to the next slice at the end.
|
||||
+ *
|
||||
+ * This is both for efficiency (we want this function to be as fast as possible)
|
||||
+ * and because locking the TEB list is hard otherwise—we need to safely access
|
||||
+ * the TEB list, but cannot do so using any of these synchronization primitives,
|
||||
+ * and we may need to access the TEB list before being inserted into it (e.g.
|
||||
+ * from heap locks, or the TEB list lock itself.)
|
||||
+ */
|
||||
+
|
||||
+struct addr_wait_entry
|
||||
+#define FUTEX_ADDR_BLOCK_SIZE (65536 / sizeof(void *))
|
||||
+static void **futex_addr_blocks[4096];
|
||||
+
|
||||
+static unsigned int tid_to_index( DWORD tid, unsigned int *block_idx )
|
||||
+{
|
||||
+ void *addr;
|
||||
+ HANDLE tid;
|
||||
+};
|
||||
+
|
||||
+struct addr_wait_array
|
||||
+{
|
||||
+ struct addr_wait_entry entries[(0x1000 - sizeof(struct addr_wait_entry *)) / sizeof(struct addr_wait_entry)];
|
||||
+ struct addr_wait_array *next;
|
||||
+};
|
||||
+
|
||||
+static struct addr_wait_array first_addr_wait_array;
|
||||
+
|
||||
+static struct addr_wait_entry *addr_wait_allocate_entry( HANDLE tid )
|
||||
+{
|
||||
+ struct addr_wait_array *array = &first_addr_wait_array;
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ struct addr_wait_array *new_array = NULL;
|
||||
+ SIZE_T size = sizeof(*new_array);
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ for (i = 0; i < ARRAY_SIZE(array->entries); ++i)
|
||||
+ {
|
||||
+ if (!array->entries[i].tid && !InterlockedCompareExchangePointer( &array->entries[i].tid, tid, NULL ))
|
||||
+ return &array->entries[i];
|
||||
+ }
|
||||
+
|
||||
+ if (!array->next) break;
|
||||
+ array = array->next;
|
||||
+ }
|
||||
+
|
||||
+ if (NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&new_array, 0, &size, MEM_COMMIT, PAGE_READWRITE ))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (InterlockedCompareExchangePointer( (void **)&array->next, new_array, NULL ))
|
||||
+ {
|
||||
+ /* another thread beat us to it */
|
||||
+ NtFreeVirtualMemory( NtCurrentProcess(), (void **)&new_array, &size, MEM_RELEASE );
|
||||
+ }
|
||||
+ /* start searching again from the new array */
|
||||
+ array = array->next;
|
||||
+ }
|
||||
+ unsigned int idx = (tid >> 2) - 1;
|
||||
+ *block_idx = idx / FUTEX_ADDR_BLOCK_SIZE;
|
||||
+ return idx % FUTEX_ADDR_BLOCK_SIZE;
|
||||
+}
|
||||
+
|
||||
+void addr_wait_free_entry(void)
|
||||
+static HANDLE index_to_tid( unsigned int block_idx, unsigned int idx )
|
||||
+{
|
||||
+ struct addr_wait_entry *entry = NtCurrentTeb()->ReservedForPerf;
|
||||
+ if (entry)
|
||||
+ InterlockedExchangePointer( &entry->tid, NULL );
|
||||
+ return (HANDLE)((((block_idx * FUTEX_ADDR_BLOCK_SIZE) + idx) + 1) << 2);
|
||||
+}
|
||||
+
|
||||
+static void **get_futex_entry( DWORD tid )
|
||||
+{
|
||||
+ unsigned int block_idx, idx = tid_to_index( tid, &block_idx );
|
||||
+
|
||||
+ if (block_idx > ARRAY_SIZE(futex_addr_blocks))
|
||||
+ {
|
||||
+ FIXME( "tid %#x is too high\n", tid );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!futex_addr_blocks[block_idx])
|
||||
+ {
|
||||
+ SIZE_T size = FUTEX_ADDR_BLOCK_SIZE * sizeof(void *);
|
||||
+ void *ptr = NULL;
|
||||
+
|
||||
+ if (NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &size, MEM_COMMIT, PAGE_READWRITE ))
|
||||
+ return NULL;
|
||||
+ if (InterlockedCompareExchangePointer( (void **)&futex_addr_blocks[block_idx], ptr, NULL ))
|
||||
+ NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE ); /* someone beat us to it */
|
||||
+ }
|
||||
+
|
||||
+ return &futex_addr_blocks[block_idx][idx % FUTEX_ADDR_BLOCK_SIZE];
|
||||
+}
|
||||
+
|
||||
+static BOOL compare_addr( const void *addr, const void *cmp, SIZE_T size )
|
||||
@ -139,7 +97,7 @@ index f1263ae33fd..d652f55b630 100644
|
||||
const LARGE_INTEGER *timeout )
|
||||
{
|
||||
- return unix_funcs->RtlWaitOnAddress( addr, cmp, size, timeout );
|
||||
+ struct addr_wait_entry *entry = NtCurrentTeb()->ReservedForPerf;
|
||||
+ void **entry = get_futex_entry( GetCurrentThreadId() );
|
||||
+ NTSTATUS ret;
|
||||
+
|
||||
+ TRACE("addr %p cmp %p size %#Ix timeout %s\n", addr, cmp, size, debugstr_timeout( timeout ));
|
||||
@ -147,14 +105,9 @@ index f1263ae33fd..d652f55b630 100644
|
||||
+ if (size != 1 && size != 2 && size != 4 && size != 8)
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ if (!entry)
|
||||
+ {
|
||||
+ if (!(entry = addr_wait_allocate_entry( NtCurrentTeb()->ClientId.UniqueThread )))
|
||||
+ return STATUS_NO_MEMORY;
|
||||
+ NtCurrentTeb()->ReservedForPerf = entry;
|
||||
+ }
|
||||
+ if (!entry) return STATUS_NO_MEMORY;
|
||||
+
|
||||
+ InterlockedExchangePointer( &entry->addr, (void *)addr );
|
||||
+ InterlockedExchangePointer( entry, (void *)addr );
|
||||
+
|
||||
+ /* Ensure that the compare-and-swap above is ordered before the comparison
|
||||
+ * below. This barrier is paired with another in RtlWakeByAddress*().
|
||||
@ -178,24 +131,24 @@ index f1263ae33fd..d652f55b630 100644
|
||||
+
|
||||
+ if (!compare_addr( addr, cmp, size ))
|
||||
+ {
|
||||
+ InterlockedExchangePointer( &entry->addr, NULL );
|
||||
+ InterlockedExchangePointer( entry, NULL );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ ret = NtWaitForAlertByThreadId( NULL, timeout );
|
||||
+ InterlockedExchangePointer( &entry->addr, NULL );
|
||||
+ InterlockedExchangePointer( entry, NULL );
|
||||
+ if (ret == STATUS_ALERTED) ret = STATUS_SUCCESS;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -544,7 +681,26 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||
@@ -544,7 +649,29 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||
*/
|
||||
void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
{
|
||||
- return unix_funcs->RtlWakeAddressAll( addr );
|
||||
+ struct addr_wait_array *array;
|
||||
+ unsigned int i;
|
||||
+ unsigned int i, j;
|
||||
+ void **block;
|
||||
+
|
||||
+ TRACE("%p\n", addr);
|
||||
+
|
||||
@ -206,24 +159,27 @@ index f1263ae33fd..d652f55b630 100644
|
||||
+ */
|
||||
+ MemoryBarrier();
|
||||
+
|
||||
+ for (array = &first_addr_wait_array; array != NULL; array = array->next)
|
||||
+ for (i = 0; i < ARRAY_SIZE(futex_addr_blocks); ++i)
|
||||
+ {
|
||||
+ for (i = 0; i < ARRAY_SIZE(array->entries); ++i)
|
||||
+ block = futex_addr_blocks[i];
|
||||
+ if (!block) continue;
|
||||
+
|
||||
+ for (j = 0; j < FUTEX_ADDR_BLOCK_SIZE; ++j)
|
||||
+ {
|
||||
+ if (array->entries[i].addr == addr)
|
||||
+ NtAlertThreadByThreadId( array->entries[i].tid );
|
||||
+ if (block[j] == addr)
|
||||
+ NtAlertThreadByThreadId( index_to_tid( i, j ) );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -552,5 +708,28 @@ void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
@@ -552,5 +679,30 @@ void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
*/
|
||||
void WINAPI RtlWakeAddressSingle( const void *addr )
|
||||
{
|
||||
- return unix_funcs->RtlWakeAddressSingle( addr );
|
||||
+ struct addr_wait_array *array;
|
||||
+ unsigned int i;
|
||||
+ unsigned int i, j;
|
||||
+ void **block;
|
||||
+
|
||||
+ TRACE("%p\n", addr);
|
||||
+
|
||||
@ -234,37 +190,26 @@ index f1263ae33fd..d652f55b630 100644
|
||||
+ */
|
||||
+ MemoryBarrier();
|
||||
+
|
||||
+ for (array = &first_addr_wait_array; array != NULL; array = array->next)
|
||||
+ for (i = 0; i < ARRAY_SIZE(futex_addr_blocks); ++i)
|
||||
+ {
|
||||
+ for (i = 0; i < ARRAY_SIZE(array->entries); ++i)
|
||||
+ block = futex_addr_blocks[i];
|
||||
+ if (!block) continue;
|
||||
+
|
||||
+ for (j = 0; j < FUTEX_ADDR_BLOCK_SIZE; ++j)
|
||||
+ {
|
||||
+ if (array->entries[i].addr == addr
|
||||
+ && InterlockedCompareExchangePointer( &array->entries[i].addr, NULL, (void *)addr ) == addr)
|
||||
+ if (block[j] == addr && InterlockedCompareExchangePointer( &block[j], NULL, (void *)addr ) == addr)
|
||||
+ {
|
||||
+ NtAlertThreadByThreadId( array->entries[i].tid );
|
||||
+ NtAlertThreadByThreadId( index_to_tid( i, j ) );
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
|
||||
index 25496609f08..4f395336428 100644
|
||||
--- a/dlls/ntdll/thread.c
|
||||
+++ b/dlls/ntdll/thread.c
|
||||
@@ -84,6 +84,8 @@ void WINAPI RtlExitUserThread( ULONG status )
|
||||
NtQueryInformationThread( GetCurrentThread(), ThreadAmILastThread, &last, sizeof(last), NULL );
|
||||
if (last) RtlExitUserProcess( status );
|
||||
LdrShutdownThread();
|
||||
+ /* must be done last, in particular after any heap allocations */
|
||||
+ addr_wait_free_entry();
|
||||
for (;;) NtTerminateThread( GetCurrentThread(), status );
|
||||
}
|
||||
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index 4c76865019b..d7fc60cad2f 100644
|
||||
index e4c062cea98..3a4a943c65f 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1753,9 +1753,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -1816,9 +1816,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -275,10 +220,10 @@ index 4c76865019b..d7fc60cad2f 100644
|
||||
fast_RtlpUnWaitCriticalSection,
|
||||
fast_RtlDeleteCriticalSection,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 7d6423083e1..41005425a90 100644
|
||||
index 4fa890e5acc..8394a1b8601 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -77,10 +77,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
@@ -80,10 +80,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
|
||||
HANDLE keyed_event = 0;
|
||||
|
||||
@ -289,7 +234,7 @@ index 7d6423083e1..41005425a90 100644
|
||||
static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
{
|
||||
if (!timeout) return "(infinite)";
|
||||
@@ -190,24 +186,6 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE
|
||||
@@ -193,24 +189,6 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE
|
||||
#endif
|
||||
|
||||
|
||||
@ -314,7 +259,7 @@ index 7d6423083e1..41005425a90 100644
|
||||
/* create a struct security_descriptor and contained information in one contiguous piece of memory */
|
||||
NTSTATUS alloc_object_attributes( const OBJECT_ATTRIBUTES *attr, struct object_attributes **ret,
|
||||
data_size_t *ret_len )
|
||||
@@ -2836,71 +2814,6 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
|
||||
@@ -2911,71 +2889,6 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -386,7 +331,7 @@ index 7d6423083e1..41005425a90 100644
|
||||
#else
|
||||
|
||||
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -2943,79 +2856,4 @@ NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value
|
||||
@@ -3018,79 +2931,4 @@ NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 9141708f675ec4aca0551249082dc7b494135bad Mon Sep 17 00:00:00 2001
|
||||
From fd8bfe5f17e0c95cdaf5125f4f4a18ad7b06cfd8 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:30:52 -0500
|
||||
Subject: [PATCH] ntdll: Merge critsection.c into sync.c.
|
||||
@ -12,7 +12,7 @@ Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
delete mode 100644 dlls/ntdll/critsection.c
|
||||
|
||||
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
|
||||
index b2f63d9f63a..5ef28d2f722 100644
|
||||
index 0fdfb83df15..2e79843890d 100644
|
||||
--- a/dlls/ntdll/Makefile.in
|
||||
+++ b/dlls/ntdll/Makefile.in
|
||||
@@ -9,7 +9,6 @@ EXTRADLLFLAGS = -mno-cygwin -nodefaultlibs -Wl,--image-base,0x7bc00000
|
||||
@ -573,7 +573,7 @@ index fe7d933c0fa..00000000000
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index be462f27881..b8465c53832 100644
|
||||
index 348f260c3b0..c73fb09da47 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -2,7 +2,7 @@
|
||||
@ -585,7 +585,7 @@ index be462f27881..b8465c53832 100644
|
||||
* Copyright 1999, 2000 Juergen Schmied
|
||||
* Copyright 2003 Eric Pouech
|
||||
*
|
||||
@@ -38,6 +38,7 @@
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
@ -593,7 +593,7 @@ index be462f27881..b8465c53832 100644
|
||||
|
||||
static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
{
|
||||
@@ -696,3 +697,334 @@ void WINAPI RtlWakeAddressSingle( const void *addr )
|
||||
@@ -706,3 +707,334 @@ void WINAPI RtlWakeAddressSingle( const void *addr )
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -929,5 +929,5 @@ index be462f27881..b8465c53832 100644
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
--
|
||||
2.29.2
|
||||
2.30.2
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 7ac2eff4652e8ce16550c27b2378e2dc64d54122 Mon Sep 17 00:00:00 2001
|
||||
From 098b4dc3d374b5ed26dbcd0be643c961f1fa156f Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:38:09 -0500
|
||||
Subject: [PATCH] ntdll: Reimplement the critical section fast path on top of
|
||||
@ -14,10 +14,10 @@ Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
5 files changed, 24 insertions(+), 131 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 09975ac3d45..97a5ce7fffa 100644
|
||||
index c73fb09da47..6edf104c5e9 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -765,19 +765,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -738,19 +738,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
|
||||
static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
@ -52,7 +52,7 @@ index 09975ac3d45..97a5ce7fffa 100644
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -867,8 +874,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -840,8 +847,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
|
||||
crit->DebugInfo = NULL;
|
||||
}
|
||||
@ -61,7 +61,7 @@ index 09975ac3d45..97a5ce7fffa 100644
|
||||
}
|
||||
else NtClose( crit->LockSemaphore );
|
||||
crit->LockSemaphore = 0;
|
||||
@@ -944,12 +949,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -917,12 +922,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
@ -83,10 +83,10 @@ index 09975ac3d45..97a5ce7fffa 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index d7fc60cad2f..fe710e9d1f5 100644
|
||||
index 3a4a943c65f..579c73b2ad7 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1753,9 +1753,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -1816,9 +1816,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -97,10 +97,10 @@ index d7fc60cad2f..fe710e9d1f5 100644
|
||||
fast_RtlAcquireSRWLockExclusive,
|
||||
fast_RtlTryAcquireSRWLockShared,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 41005425a90..6b97028fb68 100644
|
||||
index 8394a1b8601..a7cce945e97 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2409,115 +2409,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
@@ -2484,115 +2484,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
}
|
||||
|
||||
|
||||
@ -217,10 +217,10 @@ index 41005425a90..6b97028fb68 100644
|
||||
|
||||
/* Futex-based SRW lock implementation:
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 923b888ce68..1524a532a88 100644
|
||||
index a5bade02b8a..bd7c4a8068c 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -105,9 +105,6 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
|
||||
@@ -82,9 +82,6 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
|
||||
extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN;
|
@ -1,4 +1,4 @@
|
||||
From 65b24120d7a4bb05712bcb559d55a30d5a498002 Mon Sep 17 00:00:00 2001
|
||||
From 83486871ac972952b78519bd68579919de8f51d2 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 31 Aug 2020 23:55:29 -0500
|
||||
Subject: [PATCH] ntdll: Get rid of the direct futex path for condition
|
||||
@ -14,7 +14,7 @@ Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
5 files changed, 9 insertions(+), 96 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 97a5ce7fffa..1e6afc4cfc8 100644
|
||||
index 6edf104c5e9..4b92379a0ff 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -449,11 +449,8 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
@ -80,10 +80,10 @@ index 97a5ce7fffa..1e6afc4cfc8 100644
|
||||
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
|
||||
RtlAcquireSRWLockShared( lock );
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index fe710e9d1f5..36899ba57e3 100644
|
||||
index 579c73b2ad7..90fb4e4a899 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1759,8 +1759,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -1822,8 +1822,6 @@ static struct unix_funcs unix_funcs =
|
||||
fast_RtlAcquireSRWLockShared,
|
||||
fast_RtlReleaseSRWLockExclusive,
|
||||
fast_RtlReleaseSRWLockShared,
|
||||
@ -93,10 +93,10 @@ index fe710e9d1f5..36899ba57e3 100644
|
||||
ntdll_ceil,
|
||||
ntdll_cos,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 6b97028fb68..d4092438644 100644
|
||||
index a7cce945e97..e3c957e1181 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -166,23 +166,6 @@ static int *get_futex(void **ptr)
|
||||
@@ -169,23 +169,6 @@ static int *get_futex(void **ptr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ index 6b97028fb68..d4092438644 100644
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2661,50 +2644,6 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -2736,50 +2719,6 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ index 6b97028fb68..d4092438644 100644
|
||||
#else
|
||||
|
||||
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -2737,14 +2676,4 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -2812,14 +2751,4 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -187,10 +187,10 @@ index 6b97028fb68..d4092438644 100644
|
||||
-
|
||||
#endif
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 1524a532a88..91b6451ade1 100644
|
||||
index bd7c4a8068c..6a67dbd9445 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -111,10 +111,7 @@ extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLS
|
||||
@@ -88,10 +88,7 @@ extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLS
|
||||
extern NTSTATUS CDECL fast_RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
@ -1,4 +1,4 @@
|
||||
From ddc8ae251a344ad7e7e11844b03fe0eaaa553084 Mon Sep 17 00:00:00 2001
|
||||
From cfb789e5a0b1f5ac624cc98be68694168fec4503 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Sun, 22 Nov 2020 20:51:10 -0600
|
||||
Subject: [PATCH] ntdll: Reimplement SRW locks on top of Win32 futexes.
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
5 files changed, 142 insertions(+), 502 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
index 4b92379a0ff..2edc9f8d558 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -160,127 +160,24 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu
|
||||
@ -74,13 +74,15 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
-#endif
|
||||
-
|
||||
-static inline void srwlock_check_invalid( unsigned int val )
|
||||
-{
|
||||
+struct srw_lock
|
||||
{
|
||||
- /* Throw exception if it's impossible to acquire/release this lock. */
|
||||
- if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) == SRWLOCK_MASK_EXCLUSIVE_QUEUE ||
|
||||
- (val & SRWLOCK_MASK_SHARED_QUEUE) == SRWLOCK_MASK_SHARED_QUEUE)
|
||||
- RtlRaiseStatus(STATUS_RESOURCE_NOT_OWNED);
|
||||
-}
|
||||
-
|
||||
+ short exclusive_waiters;
|
||||
|
||||
-static inline unsigned int srwlock_lock_exclusive( unsigned int *dest, int incr )
|
||||
-{
|
||||
- unsigned int val, tmp;
|
||||
@ -120,8 +122,7 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
-}
|
||||
-
|
||||
-static inline void srwlock_leave_exclusive( RTL_SRWLOCK *lock, unsigned int val )
|
||||
+struct srw_lock
|
||||
{
|
||||
-{
|
||||
- /* Used when a thread leaves an exclusive section. If there are other
|
||||
- * exclusive access threads they are processed first, followed by
|
||||
- * the shared waiters. */
|
||||
@ -134,8 +135,7 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
- NtReleaseKeyedEvent( 0, srwlock_key_shared(lock), FALSE, NULL );
|
||||
- }
|
||||
-}
|
||||
+ short exclusive_waiters;
|
||||
|
||||
-
|
||||
-static inline void srwlock_leave_shared( RTL_SRWLOCK *lock, unsigned int val )
|
||||
-{
|
||||
- /* Wake up one exclusive thread as soon as the last shared access thread
|
||||
@ -167,7 +167,9 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
- if (unix_funcs->fast_RtlAcquireSRWLockExclusive( lock ) != STATUS_NOT_IMPLEMENTED)
|
||||
- return;
|
||||
+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock };
|
||||
+
|
||||
|
||||
- if (srwlock_lock_exclusive( (unsigned int *)&lock->Ptr, SRWLOCK_RES_EXCLUSIVE ))
|
||||
- NtWaitForKeyedEvent( 0, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
+ InterlockedIncrement16( &u.s->exclusive_waiters );
|
||||
+
|
||||
+ for (;;)
|
||||
@ -192,9 +194,7 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
+ wait = TRUE;
|
||||
+ }
|
||||
+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l);
|
||||
|
||||
- if (srwlock_lock_exclusive( (unsigned int *)&lock->Ptr, SRWLOCK_RES_EXCLUSIVE ))
|
||||
- NtWaitForKeyedEvent( 0, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
+
|
||||
+ if (!wait) return;
|
||||
+ RtlWaitOnAddress( &u.s->owners, &new.s.owners, sizeof(short), NULL );
|
||||
+ }
|
||||
@ -206,11 +206,11 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- unsigned int val, tmp;
|
||||
-
|
||||
- if (unix_funcs->fast_RtlAcquireSRWLockShared( lock ) != STATUS_NOT_IMPLEMENTED)
|
||||
- return;
|
||||
+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock };
|
||||
|
||||
- if (unix_funcs->fast_RtlAcquireSRWLockShared( lock ) != STATUS_NOT_IMPLEMENTED)
|
||||
- return;
|
||||
-
|
||||
- /* Acquires a shared lock. If it's currently not possible to add elements to
|
||||
- * the shared queue, then request exclusive access instead. */
|
||||
- for (val = *(unsigned int *)&lock->Ptr;; val = tmp)
|
||||
@ -268,14 +268,14 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
- return;
|
||||
+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock };
|
||||
+ union { struct srw_lock s; LONG l; } old, new;
|
||||
+
|
||||
|
||||
- srwlock_leave_exclusive( lock, srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_EXCLUSIVE ) - SRWLOCK_RES_EXCLUSIVE );
|
||||
+ do
|
||||
+ {
|
||||
+ old.s = *u.s;
|
||||
+ new = old;
|
||||
|
||||
- srwlock_leave_exclusive( lock, srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_EXCLUSIVE ) - SRWLOCK_RES_EXCLUSIVE );
|
||||
+
|
||||
+ if (old.s.owners != -1) ERR("Lock %p is not owned exclusive!\n", lock);
|
||||
+
|
||||
+ new.s.owners = 0;
|
||||
@ -296,14 +296,14 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
- return;
|
||||
+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock };
|
||||
+ union { struct srw_lock s; LONG l; } old, new;
|
||||
+
|
||||
|
||||
- srwlock_leave_shared( lock, srwlock_lock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_SHARED ) - SRWLOCK_RES_SHARED );
|
||||
+ do
|
||||
+ {
|
||||
+ old.s = *u.s;
|
||||
+ new = old;
|
||||
|
||||
- srwlock_leave_shared( lock, srwlock_lock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_SHARED ) - SRWLOCK_RES_SHARED );
|
||||
+
|
||||
+ if (old.s.owners == -1) ERR("Lock %p is owned exclusive!\n", lock);
|
||||
+ else if (!old.s.owners) ERR("Lock %p is not owned shared!\n", lock);
|
||||
+
|
||||
@ -330,7 +330,9 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
+ {
|
||||
+ old.s = *u.s;
|
||||
+ new.s = old.s;
|
||||
+
|
||||
|
||||
- return InterlockedCompareExchange( (int *)&lock->Ptr, SRWLOCK_MASK_IN_EXCLUSIVE |
|
||||
- SRWLOCK_RES_EXCLUSIVE, 0 ) == 0;
|
||||
+ if (!old.s.owners)
|
||||
+ {
|
||||
+ /* Not locked exclusive or shared. We can try to grab it. */
|
||||
@ -342,9 +344,7 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
+ ret = FALSE;
|
||||
+ }
|
||||
+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l);
|
||||
|
||||
- return InterlockedCompareExchange( (int *)&lock->Ptr, SRWLOCK_MASK_IN_EXCLUSIVE |
|
||||
- SRWLOCK_RES_EXCLUSIVE, 0 ) == 0;
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
@ -392,10 +392,10 @@ index 1e6afc4cfc8..93a6a5fd7de 100644
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index 36899ba57e3..6a7eb5d7af1 100644
|
||||
index 90fb4e4a899..26bfa961794 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1753,12 +1753,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -1816,12 +1816,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -409,10 +409,10 @@ index 36899ba57e3..6a7eb5d7af1 100644
|
||||
ntdll_ceil,
|
||||
ntdll_cos,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index d4092438644..b67f5fc8f10 100644
|
||||
index e3c957e1181..97dcd5b5026 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -114,8 +114,6 @@ static inline ULONGLONG monotonic_counter(void)
|
||||
@@ -117,8 +117,6 @@ static inline ULONGLONG monotonic_counter(void)
|
||||
|
||||
#define FUTEX_WAIT 0
|
||||
#define FUTEX_WAKE 1
|
||||
@ -421,7 +421,7 @@ index d4092438644..b67f5fc8f10 100644
|
||||
|
||||
static int futex_private = 128;
|
||||
|
||||
@@ -129,16 +127,6 @@ static inline int futex_wake( const int *addr, int val )
|
||||
@@ -132,16 +130,6 @@ static inline int futex_wake( const int *addr, int val )
|
||||
return syscall( __NR_futex, addr, FUTEX_WAKE | futex_private, val, NULL, 0, 0 );
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ index d4092438644..b67f5fc8f10 100644
|
||||
static inline int use_futexes(void)
|
||||
{
|
||||
static int supported = -1;
|
||||
@@ -156,16 +144,6 @@ static inline int use_futexes(void)
|
||||
@@ -159,16 +147,6 @@ static inline int use_futexes(void)
|
||||
return supported;
|
||||
}
|
||||
|
||||
@ -455,8 +455,8 @@ index d4092438644..b67f5fc8f10 100644
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2390,290 +2368,3 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
return NtWaitForSingleObject( ntdll_get_thread_data()->tid_alert_event, FALSE, timeout );
|
||||
@@ -2465,290 +2443,3 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
return status;
|
||||
#endif
|
||||
}
|
||||
-
|
||||
@ -747,10 +747,10 @@ index d4092438644..b67f5fc8f10 100644
|
||||
-
|
||||
-#endif
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 91b6451ade1..ffce7328600 100644
|
||||
index 6a67dbd9445..8184d8e5e79 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -105,12 +105,6 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
|
||||
@@ -82,12 +82,6 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
|
||||
extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN;
|
@ -2938,24 +2938,22 @@ fi
|
||||
# | * [#50292] Process-local synchronization objects use private interfaces into the Unix library
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/ntdll/Makefile.in, dlls/ntdll/critsection.c, dlls/ntdll/ntdll.spec, dlls/ntdll/ntdll_misc.h, dlls/ntdll/sync.c,
|
||||
# | dlls/ntdll/tests/Makefile.in, dlls/ntdll/tests/om.c, dlls/ntdll/tests/sync.c, dlls/ntdll/thread.c,
|
||||
# | dlls/ntdll/unix/loader.c, dlls/ntdll/unix/sync.c, dlls/ntdll/unix/thread.c, dlls/ntdll/unix/unix_private.h,
|
||||
# | dlls/ntdll/unix/virtual.c, dlls/ntdll/unixlib.h, include/winternl.h
|
||||
# | * dlls/ntdll/Makefile.in, dlls/ntdll/critsection.c, dlls/ntdll/ntdll.spec, dlls/ntdll/sync.c,
|
||||
# | dlls/ntdll/tests/Makefile.in, dlls/ntdll/tests/om.c, dlls/ntdll/tests/sync.c, dlls/ntdll/unix/loader.c,
|
||||
# | dlls/ntdll/unix/sync.c, dlls/ntdll/unix/unix_private.h, dlls/ntdll/unixlib.h, include/winternl.h
|
||||
# |
|
||||
if test "$enable_ntdll_NtAlertThreadByThreadId" -eq 1; then
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0001-ntdll-tests-Move-some-tests-to-a-new-sync.c-file.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0002-ntdll-tests-Add-some-tests-for-Rtl-resources.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0003-ntdll-Use-a-separate-mutex-to-lock-the-TEB-list.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0004-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0005-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-id-alerts-on-top-of-futexes-i.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0007-ntdll-Implement-thread-id-alerts-on-top-of-Mach-sema.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0010-ntdll-Merge-critsection.c-into-sync.c.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-the-critical-section-fast-path-on-.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0012-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0013-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0003-ntdll-Implement-NtAlertThreadByThreadId-and-NtWaitFo.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0004-ntdll-tests-Add-basic-tests-for-thread-id-alert-func.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0005-ntdll-Implement-thread-ID-alerts-using-futexes-if-po.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0008-ntdll-Merge-critsection.c-into-sync.c.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0010-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch
|
||||
patch_apply ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch
|
||||
fi
|
||||
|
||||
# Patchset ntdll-NtQuerySection
|
||||
|
Loading…
Reference in New Issue
Block a user