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:
Zebediah Figura 2021-04-30 18:09:47 -05:00
parent 7d496bf02c
commit a1a2d65488
15 changed files with 816 additions and 786 deletions

View File

@ -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();
+}
--

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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