mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
ntdll-NtAlertThreadByThreadId: Make Win32 futexes fair.
Resident Evil 8 depends on this.
This commit is contained in:
parent
feb91195ff
commit
4eaa5b69b8
@ -1,22 +1,26 @@
|
||||
From 9e5d23232d1e857e1b57292f0f56487943fb0ba4 Mon Sep 17 00:00:00 2001
|
||||
From 683cdfce393f1a4fca23d1520866d3e663a8c60f Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Mon, 2 Nov 2020 20:24:07 -0600
|
||||
Date: Mon, 7 Jun 2021 16:26:18 -0500
|
||||
Subject: [PATCH] ntdll: Reimplement Win32 futexes on top of thread-ID alerts.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/sync.c | 158 +++++++++++++++++++++++++++++++++++++-
|
||||
dlls/ntdll/sync.c | 215 ++++++++++++++++++++++++++++++++++++++-
|
||||
dlls/ntdll/unix/loader.c | 3 -
|
||||
dlls/ntdll/unix/sync.c | 162 ---------------------------------------
|
||||
dlls/ntdll/unixlib.h | 4 -
|
||||
4 files changed, 155 insertions(+), 172 deletions(-)
|
||||
dlls/ntdll/unix/sync.c | 162 -----------------------------
|
||||
dlls/ntdll/unixlib.h | 6 +-
|
||||
4 files changed, 213 insertions(+), 173 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index f1263ae33fd..348f260c3b0 100644
|
||||
index f1263ae33fd..c0a6e3a729e 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -36,6 +36,13 @@
|
||||
@@ -34,8 +34,16 @@
|
||||
#include "windef.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
+#include "wine/list.h"
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
+WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
@ -29,48 +33,68 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
|
||||
/******************************************************************
|
||||
* RtlRunOnceInitialize (NTDLL.@)
|
||||
@@ -530,13 +537,111 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
@@ -530,13 +538,142 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
return status;
|
||||
}
|
||||
|
||||
+/* RtlWaitOnAddress() and RtlWakeAddress*(), hereafter referred to as "Win32
|
||||
+ * futexes", offer futex-like semantics with a variable set of address sizes,
|
||||
+ * but are limited to a single process. They are also fair—the documentation
|
||||
+ * specifies this, and tests bear it out.
|
||||
+ *
|
||||
+ * On Windows they are implemented using NtAlertThreadByThreadId and
|
||||
+ * NtWaitForAlertByThreadId, which manipulate a single flag (similar to a
|
||||
+ * manual-reset event) per thread. This can be tested by attempting to wake a
|
||||
+ * thread waiting in RtlWaitOnAddress() via NtAlertThreadByThreadId.
|
||||
+ */
|
||||
+
|
||||
+#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 )
|
||||
+struct futex_entry
|
||||
+{
|
||||
+ unsigned int idx = (tid >> 2) - 1;
|
||||
+ *block_idx = idx / FUTEX_ADDR_BLOCK_SIZE;
|
||||
+ return idx % FUTEX_ADDR_BLOCK_SIZE;
|
||||
+ struct list entry;
|
||||
+ const void *addr;
|
||||
+ DWORD tid;
|
||||
+};
|
||||
+
|
||||
+struct futex_queue
|
||||
+{
|
||||
+ struct list queue;
|
||||
+ LONG lock;
|
||||
+};
|
||||
+
|
||||
+static struct futex_queue futex_queues[256];
|
||||
+
|
||||
+static struct futex_queue *get_futex_queue( const void *addr )
|
||||
+{
|
||||
+ ULONG_PTR val = (ULONG_PTR)addr;
|
||||
+
|
||||
+ return &futex_queues[(val >> 4) % ARRAY_SIZE(futex_queues)];
|
||||
+}
|
||||
+
|
||||
+static HANDLE index_to_tid( unsigned int block_idx, unsigned int idx )
|
||||
+static void spin_rdlock( LONG *lock )
|
||||
+{
|
||||
+ return (HANDLE)((((block_idx * FUTEX_ADDR_BLOCK_SIZE) + idx) + 1) << 2);
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ LONG old = *lock;
|
||||
+ if (old != -1 && InterlockedCompareExchange( lock, old + 1, old ) == old)
|
||||
+ return;
|
||||
+ YieldProcessor();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void **get_futex_entry( DWORD tid )
|
||||
+static void spin_rdunlock( LONG *lock )
|
||||
+{
|
||||
+ unsigned int block_idx, idx = tid_to_index( tid, &block_idx );
|
||||
+ InterlockedDecrement( lock );
|
||||
+}
|
||||
+
|
||||
+ if (block_idx > ARRAY_SIZE(futex_addr_blocks))
|
||||
+ {
|
||||
+ FIXME( "tid %#x is too high\n", tid );
|
||||
+ return NULL;
|
||||
+ }
|
||||
+static void spin_wrlock( LONG *lock )
|
||||
+{
|
||||
+ while (InterlockedCompareExchange( lock, -1, 0 ))
|
||||
+ YieldProcessor();
|
||||
+}
|
||||
+
|
||||
+ 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 void spin_wrunlock( LONG *lock )
|
||||
+{
|
||||
+ InterlockedExchange( lock, 0 );
|
||||
+}
|
||||
+
|
||||
+static BOOL compare_addr( const void *addr, const void *cmp, SIZE_T size )
|
||||
@ -97,7 +121,8 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
const LARGE_INTEGER *timeout )
|
||||
{
|
||||
- return unix_funcs->RtlWaitOnAddress( addr, cmp, size, timeout );
|
||||
+ void **entry = get_futex_entry( GetCurrentThreadId() );
|
||||
+ struct futex_queue *queue = get_futex_queue( addr );
|
||||
+ struct futex_entry entry;
|
||||
+ NTSTATUS ret;
|
||||
+
|
||||
+ TRACE("addr %p cmp %p size %#Ix timeout %s\n", addr, cmp, size, debugstr_timeout( timeout ));
|
||||
@ -105,12 +130,17 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
+ if (size != 1 && size != 2 && size != 4 && size != 8)
|
||||
+ return STATUS_INVALID_PARAMETER;
|
||||
+
|
||||
+ if (!entry) return STATUS_NO_MEMORY;
|
||||
+ entry.addr = addr;
|
||||
+ entry.tid = GetCurrentThreadId();
|
||||
+
|
||||
+ InterlockedExchangePointer( entry, (void *)addr );
|
||||
+ spin_wrlock( &queue->lock );
|
||||
+ if (!queue->queue.next)
|
||||
+ list_init(&queue->queue);
|
||||
+ list_add_tail( &queue->queue, &entry.entry );
|
||||
+ spin_wrunlock( &queue->lock );
|
||||
+
|
||||
+ /* Ensure that the compare-and-swap above is ordered before the comparison
|
||||
+ * below. This barrier is paired with another in RtlWakeByAddress*().
|
||||
+ /* Ensure that the store above is ordered before the comparison below.
|
||||
+ * This barrier is paired with another in RtlWakeByAddress*().
|
||||
+ *
|
||||
+ * In more detail, given the following sequence:
|
||||
+ *
|
||||
@ -129,26 +159,33 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
+ */
|
||||
+ MemoryBarrier();
|
||||
+
|
||||
+ if (!compare_addr( addr, cmp, size ))
|
||||
+ {
|
||||
+ InterlockedExchangePointer( entry, NULL );
|
||||
+ return STATUS_SUCCESS;
|
||||
+ }
|
||||
+ if (compare_addr( addr, cmp, size ))
|
||||
+ ret = NtWaitForAlertByThreadId( NULL, timeout );
|
||||
+ else
|
||||
+ ret = STATUS_SUCCESS;
|
||||
+
|
||||
+ spin_wrlock( &queue->lock );
|
||||
+ /* We may have already been removed by a call to RtlWakeAddressSingle(). */
|
||||
+ if (entry.addr)
|
||||
+ list_remove( &entry.entry );
|
||||
+ spin_wrunlock( &queue->lock );
|
||||
+
|
||||
+ TRACE("returning %#x\n", ret);
|
||||
+
|
||||
+ ret = NtWaitForAlertByThreadId( NULL, timeout );
|
||||
+ InterlockedExchangePointer( entry, NULL );
|
||||
+ if (ret == STATUS_ALERTED) ret = STATUS_SUCCESS;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -544,7 +649,29 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||
@@ -544,7 +681,42 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size
|
||||
*/
|
||||
void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
{
|
||||
- return unix_funcs->RtlWakeAddressAll( addr );
|
||||
+ unsigned int i, j;
|
||||
+ void **block;
|
||||
+ struct futex_queue *queue = get_futex_queue( addr );
|
||||
+ unsigned int count = 0, i;
|
||||
+ struct futex_entry *entry;
|
||||
+ DWORD tids[256];
|
||||
+
|
||||
+ TRACE("%p\n", addr);
|
||||
+
|
||||
@ -159,27 +196,39 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
+ */
|
||||
+ MemoryBarrier();
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(futex_addr_blocks); ++i)
|
||||
+ {
|
||||
+ block = futex_addr_blocks[i];
|
||||
+ if (!block) continue;
|
||||
+ spin_wrlock( &queue->lock );
|
||||
+
|
||||
+ for (j = 0; j < FUTEX_ADDR_BLOCK_SIZE; ++j)
|
||||
+ if (!queue->queue.next)
|
||||
+ list_init(&queue->queue);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY( entry, &queue->queue, struct futex_entry, entry )
|
||||
+ {
|
||||
+ if (entry->addr == addr)
|
||||
+ {
|
||||
+ if (block[j] == addr)
|
||||
+ NtAlertThreadByThreadId( index_to_tid( i, j ) );
|
||||
+ /* Try to buffer wakes, so that we don't make a system call while
|
||||
+ * holding a spinlock. */
|
||||
+ if (count < ARRAY_SIZE(tids))
|
||||
+ tids[count++] = entry->tid;
|
||||
+ else
|
||||
+ NtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)entry->tid );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_wrunlock( &queue->lock );
|
||||
+
|
||||
+ for (i = 0; i < count; ++i)
|
||||
+ NtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tids[i] );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -552,5 +679,30 @@ void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
@@ -552,5 +724,42 @@ void WINAPI RtlWakeAddressAll( const void *addr )
|
||||
*/
|
||||
void WINAPI RtlWakeAddressSingle( const void *addr )
|
||||
{
|
||||
- return unix_funcs->RtlWakeAddressSingle( addr );
|
||||
+ unsigned int i, j;
|
||||
+ void **block;
|
||||
+ struct futex_queue *queue = get_futex_queue( addr );
|
||||
+ struct futex_entry *entry;
|
||||
+ DWORD tid = 0;
|
||||
+
|
||||
+ TRACE("%p\n", addr);
|
||||
+
|
||||
@ -190,26 +239,37 @@ index f1263ae33fd..348f260c3b0 100644
|
||||
+ */
|
||||
+ MemoryBarrier();
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(futex_addr_blocks); ++i)
|
||||
+ {
|
||||
+ block = futex_addr_blocks[i];
|
||||
+ if (!block) continue;
|
||||
+ spin_wrlock( &queue->lock );
|
||||
+
|
||||
+ for (j = 0; j < FUTEX_ADDR_BLOCK_SIZE; ++j)
|
||||
+ if (!queue->queue.next)
|
||||
+ list_init(&queue->queue);
|
||||
+
|
||||
+ LIST_FOR_EACH_ENTRY( entry, &queue->queue, struct futex_entry, entry )
|
||||
+ {
|
||||
+ if (entry->addr == addr)
|
||||
+ {
|
||||
+ if (block[j] == addr && InterlockedCompareExchangePointer( &block[j], NULL, (void *)addr ) == addr)
|
||||
+ {
|
||||
+ NtAlertThreadByThreadId( index_to_tid( i, j ) );
|
||||
+ return;
|
||||
+ }
|
||||
+ /* Try to buffer wakes, so that we don't make a system call while
|
||||
+ * holding a spinlock. */
|
||||
+ tid = entry->tid;
|
||||
+
|
||||
+ /* Remove this entry from the queue, so that a simultaneous call to
|
||||
+ * RtlWakeAddressSingle() will not also wake it—two simultaneous
|
||||
+ * calls must wake at least two waiters if they exist. */
|
||||
+ entry->addr = NULL;
|
||||
+ list_remove( &entry->entry );
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ spin_wrunlock( &queue->lock );
|
||||
+
|
||||
+ if (tid) NtAlertThreadByThreadId( (HANDLE)(DWORD_PTR)tid );
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index c26028d756e..f046d2db878 100644
|
||||
index 8720660eb6b..269788bcf91 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1822,9 +1822,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -2151,9 +2151,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -220,10 +280,10 @@ index c26028d756e..f046d2db878 100644
|
||||
fast_RtlpUnWaitCriticalSection,
|
||||
fast_RtlDeleteCriticalSection,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 9ebcf60c820..5e49593fa4a 100644
|
||||
index 7f5d9a49ef5..43838e593dc 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -81,10 +81,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
@@ -78,10 +78,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
|
||||
HANDLE keyed_event = 0;
|
||||
|
||||
@ -234,7 +294,7 @@ index 9ebcf60c820..5e49593fa4a 100644
|
||||
static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
{
|
||||
if (!timeout) return "(infinite)";
|
||||
@@ -194,24 +190,6 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE
|
||||
@@ -191,24 +187,6 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE
|
||||
#endif
|
||||
|
||||
|
||||
@ -259,7 +319,7 @@ index 9ebcf60c820..5e49593fa4a 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 )
|
||||
@@ -2980,71 +2958,6 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
|
||||
@@ -2982,71 +2960,6 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable,
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -331,7 +391,7 @@ index 9ebcf60c820..5e49593fa4a 100644
|
||||
#else
|
||||
|
||||
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -3087,79 +3000,4 @@ NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value
|
||||
@@ -3089,79 +3002,4 @@ NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -412,9 +472,18 @@ index 9ebcf60c820..5e49593fa4a 100644
|
||||
- mutex_unlock( &addr_mutex );
|
||||
-}
|
||||
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
|
||||
index cbe5c9d3ccd..914a2f3b7b7 100644
|
||||
index 4b7c8b45be7..921ceedbdb2 100644
|
||||
--- a/dlls/ntdll/unixlib.h
|
||||
+++ b/dlls/ntdll/unixlib.h
|
||||
@@ -26,7 +26,7 @@
|
||||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
-#define NTDLL_UNIXLIB_VERSION 126
|
||||
+#define NTDLL_UNIXLIB_VERSION 127
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
@@ -38,10 +38,6 @@ struct unix_funcs
|
||||
/* other Win32 API functions */
|
||||
NTSTATUS (WINAPI *DbgUiIssueRemoteBreakin)( HANDLE process );
|
||||
@ -427,5 +496,5 @@ index cbe5c9d3ccd..914a2f3b7b7 100644
|
||||
/* fast locks */
|
||||
NTSTATUS (CDECL *fast_RtlpWaitForCriticalSection)( RTL_CRITICAL_SECTION *crit, int timeout );
|
||||
--
|
||||
2.30.2
|
||||
2.33.0
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
From 601db6caf92a018e469a714085c7a573c7cd8fa1 Mon Sep 17 00:00:00 2001
|
||||
From daa52c29f5fe2ba16338672bc545259d3314295c 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.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/Makefile.in | 1 -
|
||||
dlls/ntdll/critsection.c | 543 ---------------------------------------
|
||||
@ -12,10 +13,10 @@ 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 881a3b28ff1..841e1a4a943 100644
|
||||
index aac7f8eead7..29b772c7c56 100644
|
||||
--- a/dlls/ntdll/Makefile.in
|
||||
+++ b/dlls/ntdll/Makefile.in
|
||||
@@ -9,7 +9,6 @@ EXTRADLLFLAGS = -mno-cygwin -nodefaultlibs -Wl,--image-base,0x7bc00000
|
||||
@@ -11,7 +11,6 @@ EXTRADLLFLAGS = -nodefaultlibs -Wl,--image-base,0x7bc00000
|
||||
C_SRCS = \
|
||||
actctx.c \
|
||||
atom.c \
|
||||
@ -573,7 +574,7 @@ index fe7d933c0fa..00000000000
|
||||
- return STATUS_SUCCESS;
|
||||
-}
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 348f260c3b0..c73fb09da47 100644
|
||||
index c0a6e3a729e..db68a466d8a 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -2,7 +2,7 @@
|
||||
@ -585,7 +586,7 @@ index 348f260c3b0..c73fb09da47 100644
|
||||
* Copyright 1999, 2000 Juergen Schmied
|
||||
* Copyright 2003 Eric Pouech
|
||||
*
|
||||
@@ -37,6 +37,7 @@
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "ntdll_misc.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(sync);
|
||||
@ -593,11 +594,10 @@ index 348f260c3b0..c73fb09da47 100644
|
||||
|
||||
static const char *debugstr_timeout( const LARGE_INTEGER *timeout )
|
||||
{
|
||||
@@ -706,3 +707,334 @@ void WINAPI RtlWakeAddressSingle( const void *addr )
|
||||
}
|
||||
@@ -141,6 +142,337 @@ DWORD WINAPI RtlRunOnceComplete( RTL_RUN_ONCE *once, ULONG flags, void *context
|
||||
}
|
||||
}
|
||||
+
|
||||
|
||||
+
|
||||
+/***********************************************************************
|
||||
+ * Critical sections
|
||||
@ -928,6 +928,10 @@ index 348f260c3b0..c73fb09da47 100644
|
||||
+ }
|
||||
+ return STATUS_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/******************************************************************
|
||||
* RtlRunOnceExecuteOnce (NTDLL.@)
|
||||
*/
|
||||
--
|
||||
2.30.2
|
||||
2.33.0
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
From aaa6e2824cd84e2317017c5436c03621a890cc0c Mon Sep 17 00:00:00 2001
|
||||
From d43977918339fdda79e06331502254eaf456adab 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
|
||||
Win32 futexes.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/sync.c | 35 +++++++----
|
||||
dlls/ntdll/unix/loader.c | 3 -
|
||||
dlls/ntdll/unix/sync.c | 109 ---------------------------------
|
||||
dlls/ntdll/unix/unix_private.h | 4 --
|
||||
dlls/ntdll/unixlib.h | 3 -
|
||||
5 files changed, 23 insertions(+), 131 deletions(-)
|
||||
dlls/ntdll/unixlib.h | 5 +-
|
||||
5 files changed, 24 insertions(+), 132 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index c73fb09da47..6edf104c5e9 100644
|
||||
index db68a466d8a..3a47679bb60 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -738,19 +738,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -172,19 +172,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
||||
|
||||
static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
|
||||
{
|
||||
@ -52,7 +53,7 @@ index c73fb09da47..6edf104c5e9 100644
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -840,8 +847,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -274,8 +281,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
|
||||
crit->DebugInfo = NULL;
|
||||
}
|
||||
@ -61,7 +62,7 @@ index c73fb09da47..6edf104c5e9 100644
|
||||
}
|
||||
else NtClose( crit->LockSemaphore );
|
||||
crit->LockSemaphore = 0;
|
||||
@@ -917,12 +922,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
@@ -351,12 +356,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
||||
NTSTATUS ret;
|
||||
|
||||
/* debug info is cleared by MakeCriticalSectionGlobal */
|
||||
@ -83,10 +84,10 @@ index c73fb09da47..6edf104c5e9 100644
|
||||
return ret;
|
||||
}
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index e21cf8631d7..97bb9e510b2 100644
|
||||
index 269788bcf91..5302b7f1638 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1872,9 +1872,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -2151,9 +2151,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -97,10 +98,10 @@ index e21cf8631d7..97bb9e510b2 100644
|
||||
fast_RtlAcquireSRWLockExclusive,
|
||||
fast_RtlTryAcquireSRWLockShared,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 5e49593fa4a..84f7c937be3 100644
|
||||
index 43838e593dc..6a636d30f21 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -2553,115 +2553,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
@@ -2555,115 +2555,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
|
||||
#endif
|
||||
|
||||
@ -217,10 +218,10 @@ index 5e49593fa4a..84f7c937be3 100644
|
||||
|
||||
/* Futex-based SRW lock implementation:
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 090f6afdf29..5e3dbebee4c 100644
|
||||
index 6b8835bcba0..d142fa894b1 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -96,10 +96,6 @@ extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PT
|
||||
@@ -101,10 +101,6 @@ extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PT
|
||||
extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *p__wine_ctrl_routine)(void *) DECLSPEC_HIDDEN;
|
||||
extern SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock DECLSPEC_HIDDEN;
|
||||
@ -232,9 +233,18 @@ index 090f6afdf29..5e3dbebee4c 100644
|
||||
extern NTSTATUS CDECL fast_RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
|
||||
index 10b0f57fbed..37a0e2da83c 100644
|
||||
index 921ceedbdb2..d86501dfb5e 100644
|
||||
--- a/dlls/ntdll/unixlib.h
|
||||
+++ b/dlls/ntdll/unixlib.h
|
||||
@@ -26,7 +26,7 @@
|
||||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
-#define NTDLL_UNIXLIB_VERSION 127
|
||||
+#define NTDLL_UNIXLIB_VERSION 128
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
@@ -40,9 +40,6 @@ struct unix_funcs
|
||||
LONGLONG (WINAPI *RtlGetSystemTimePrecise)(void);
|
||||
|
||||
@ -246,5 +256,5 @@ index 10b0f57fbed..37a0e2da83c 100644
|
||||
NTSTATUS (CDECL *fast_RtlAcquireSRWLockExclusive)( RTL_SRWLOCK *lock );
|
||||
NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockShared)( RTL_SRWLOCK *lock );
|
||||
--
|
||||
2.30.2
|
||||
2.33.0
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
From 16e1eb20e23a8bd8129cf59efef1db06848752ed Mon Sep 17 00:00:00 2001
|
||||
From a90c16005d368581ea802f9fb2780fcb10d23566 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
|
||||
variables.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/sync.c | 24 ++++--------
|
||||
dlls/ntdll/unix/loader.c | 2 -
|
||||
dlls/ntdll/unix/sync.c | 71 ----------------------------------
|
||||
dlls/ntdll/unix/unix_private.h | 3 --
|
||||
dlls/ntdll/unixlib.h | 3 --
|
||||
5 files changed, 8 insertions(+), 95 deletions(-)
|
||||
dlls/ntdll/unixlib.h | 5 +--
|
||||
5 files changed, 9 insertions(+), 96 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 6edf104c5e9..4b92379a0ff 100644
|
||||
index 3a47679bb60..6e68d07b81b 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -449,11 +449,8 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
@@ -792,11 +792,8 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
*/
|
||||
void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
{
|
||||
@ -31,7 +32,7 @@ index 6edf104c5e9..4b92379a0ff 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -463,11 +460,8 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
@@ -806,11 +803,8 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
*/
|
||||
void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
{
|
||||
@ -45,7 +46,7 @@ index 6edf104c5e9..4b92379a0ff 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -488,12 +482,11 @@ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
@@ -831,12 +825,11 @@ void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable )
|
||||
NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, RTL_CRITICAL_SECTION *crit,
|
||||
const LARGE_INTEGER *timeout )
|
||||
{
|
||||
@ -60,7 +61,7 @@ index 6edf104c5e9..4b92379a0ff 100644
|
||||
RtlEnterCriticalSection( crit );
|
||||
return status;
|
||||
}
|
||||
@@ -520,7 +513,7 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R
|
||||
@@ -863,7 +856,7 @@ NTSTATUS WINAPI RtlSleepConditionVariableCS( RTL_CONDITION_VARIABLE *variable, R
|
||||
NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, RTL_SRWLOCK *lock,
|
||||
const LARGE_INTEGER *timeout, ULONG flags )
|
||||
{
|
||||
@ -69,7 +70,7 @@ index 6edf104c5e9..4b92379a0ff 100644
|
||||
NTSTATUS status;
|
||||
|
||||
if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED)
|
||||
@@ -528,8 +521,7 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
@@ -871,8 +864,7 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable,
|
||||
else
|
||||
RtlReleaseSRWLockExclusive( lock );
|
||||
|
||||
@ -80,10 +81,10 @@ index 6edf104c5e9..4b92379a0ff 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 9633aaf3966..c2b713597d7 100644
|
||||
index 5302b7f1638..bb25f50581c 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -2156,8 +2156,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -2157,8 +2157,6 @@ static struct unix_funcs unix_funcs =
|
||||
fast_RtlAcquireSRWLockShared,
|
||||
fast_RtlReleaseSRWLockExclusive,
|
||||
fast_RtlReleaseSRWLockShared,
|
||||
@ -93,10 +94,10 @@ index 9633aaf3966..c2b713597d7 100644
|
||||
ntdll_ceil,
|
||||
ntdll_cos,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 42ac52c9704..99be558da12 100644
|
||||
index 6a636d30f21..f0267c2df1c 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -170,23 +170,6 @@ static int *get_futex(void **ptr)
|
||||
@@ -167,23 +167,6 @@ static int *get_futex(void **ptr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -120,7 +121,7 @@ index 42ac52c9704..99be558da12 100644
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2842,50 +2825,6 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -2807,50 +2790,6 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -171,7 +172,7 @@ index 42ac52c9704..99be558da12 100644
|
||||
#else
|
||||
|
||||
NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -2918,14 +2857,4 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -2883,14 +2822,4 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -187,10 +188,10 @@ index 42ac52c9704..99be558da12 100644
|
||||
-
|
||||
#endif
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index b5a0b4121bc..dd13a976a7f 100644
|
||||
index d142fa894b1..f192215f32a 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -108,10 +108,7 @@ extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLS
|
||||
@@ -107,10 +107,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;
|
||||
@ -202,9 +203,18 @@ index b5a0b4121bc..dd13a976a7f 100644
|
||||
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
|
||||
index 3834dc78728..f7e9dc0a214 100644
|
||||
index d86501dfb5e..5b56f1f2cf1 100644
|
||||
--- a/dlls/ntdll/unixlib.h
|
||||
+++ b/dlls/ntdll/unixlib.h
|
||||
@@ -26,7 +26,7 @@
|
||||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
-#define NTDLL_UNIXLIB_VERSION 128
|
||||
+#define NTDLL_UNIXLIB_VERSION 129
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
@@ -46,9 +46,6 @@ struct unix_funcs
|
||||
NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock );
|
||||
NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock );
|
||||
|
@ -1,9 +1,10 @@
|
||||
From 8071d356061b69182746fda71ec9f1b0e9a40e3d Mon Sep 17 00:00:00 2001
|
||||
From f032b2f1811e4a13a817b69b1f81fa9171e70502 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.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
|
||||
---
|
||||
dlls/ntdll/sync.c | 313 +++++++++++++++------------------
|
||||
dlls/ntdll/unix/loader.c | 6 -
|
||||
@ -13,10 +14,10 @@ Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
5 files changed, 142 insertions(+), 501 deletions(-)
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index 4b92379a0ff..2edc9f8d558 100644
|
||||
index 6e68d07b81b..e380f3e4e93 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
|
||||
@@ -503,127 +503,24 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu
|
||||
return RtlRunOnceComplete( once, 0, context ? *context : NULL );
|
||||
}
|
||||
|
||||
@ -74,13 +75,15 @@ index 4b92379a0ff..2edc9f8d558 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 +123,7 @@ index 4b92379a0ff..2edc9f8d558 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 +136,7 @@ index 4b92379a0ff..2edc9f8d558 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
|
||||
@ -160,14 +161,16 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
|
||||
/***********************************************************************
|
||||
* RtlInitializeSRWLock (NTDLL.@)
|
||||
@@ -307,11 +204,36 @@ void WINAPI RtlInitializeSRWLock( RTL_SRWLOCK *lock )
|
||||
@@ -650,11 +547,36 @@ void WINAPI RtlInitializeSRWLock( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- 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,25 +195,23 @@ index 4b92379a0ff..2edc9f8d558 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 );
|
||||
+ }
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -323,34 +245,34 @@ void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -666,34 +588,34 @@ void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
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)
|
||||
@ -260,7 +261,7 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -358,11 +280,23 @@ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -701,11 +623,23 @@ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
{
|
||||
@ -268,16 +269,16 @@ index 4b92379a0ff..2edc9f8d558 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;
|
||||
+
|
||||
+ if (old.s.owners != -1) ERR("Lock %p is not owned exclusive!\n", lock);
|
||||
|
||||
- srwlock_leave_exclusive( lock, srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_EXCLUSIVE ) - SRWLOCK_RES_EXCLUSIVE );
|
||||
+
|
||||
+ new.s.owners = 0;
|
||||
+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l);
|
||||
+
|
||||
@ -288,7 +289,7 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -370,11 +304,22 @@ void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -713,11 +647,22 @@ void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
{
|
||||
@ -296,7 +297,9 @@ index 4b92379a0ff..2edc9f8d558 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;
|
||||
@ -304,9 +307,7 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
+
|
||||
+ 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);
|
||||
|
||||
- srwlock_leave_shared( lock, srwlock_lock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
- - SRWLOCK_RES_SHARED ) - SRWLOCK_RES_SHARED );
|
||||
+
|
||||
+ --new.s.owners;
|
||||
+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l);
|
||||
+
|
||||
@ -315,7 +316,7 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -386,13 +331,28 @@ void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
@@ -729,13 +674,28 @@ void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
{
|
||||
@ -349,7 +350,7 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -400,20 +360,29 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
@@ -743,20 +703,29 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
{
|
||||
@ -392,10 +393,10 @@ index 4b92379a0ff..2edc9f8d558 100644
|
||||
|
||||
/***********************************************************************
|
||||
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
|
||||
index f1767f2b568..99268914734 100644
|
||||
index bb25f50581c..a8dc128adcf 100644
|
||||
--- a/dlls/ntdll/unix/loader.c
|
||||
+++ b/dlls/ntdll/unix/loader.c
|
||||
@@ -1870,12 +1870,6 @@ static struct unix_funcs unix_funcs =
|
||||
@@ -2151,12 +2151,6 @@ static struct unix_funcs unix_funcs =
|
||||
#endif
|
||||
DbgUiIssueRemoteBreakin,
|
||||
RtlGetSystemTimePrecise,
|
||||
@ -409,10 +410,10 @@ index f1767f2b568..99268914734 100644
|
||||
ntdll_ceil,
|
||||
ntdll_cos,
|
||||
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c
|
||||
index 99be558da12..5a82cf7e539 100644
|
||||
index f0267c2df1c..19a499ff2c9 100644
|
||||
--- a/dlls/ntdll/unix/sync.c
|
||||
+++ b/dlls/ntdll/unix/sync.c
|
||||
@@ -118,8 +118,6 @@ static inline ULONGLONG monotonic_counter(void)
|
||||
@@ -115,8 +115,6 @@ static inline ULONGLONG monotonic_counter(void)
|
||||
|
||||
#define FUTEX_WAIT 0
|
||||
#define FUTEX_WAKE 1
|
||||
@ -421,7 +422,7 @@ index 99be558da12..5a82cf7e539 100644
|
||||
|
||||
static int futex_private = 128;
|
||||
|
||||
@@ -133,16 +131,6 @@ static inline int futex_wake( const int *addr, int val )
|
||||
@@ -130,16 +128,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 +439,7 @@ index 99be558da12..5a82cf7e539 100644
|
||||
static inline int use_futexes(void)
|
||||
{
|
||||
static int supported = -1;
|
||||
@@ -160,16 +148,6 @@ static inline int use_futexes(void)
|
||||
@@ -157,16 +145,6 @@ static inline int use_futexes(void)
|
||||
return supported;
|
||||
}
|
||||
|
||||
@ -455,7 +456,7 @@ index 99be558da12..5a82cf7e539 100644
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2572,289 +2550,3 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
@@ -2537,289 +2515,3 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -746,10 +747,10 @@ index 99be558da12..5a82cf7e539 100644
|
||||
-
|
||||
-#endif
|
||||
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
|
||||
index 452eb2790ab..8f85eb5ebc6 100644
|
||||
index f192215f32a..fc52b7d210e 100644
|
||||
--- a/dlls/ntdll/unix/unix_private.h
|
||||
+++ b/dlls/ntdll/unix/unix_private.h
|
||||
@@ -96,12 +96,6 @@ extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PT
|
||||
@@ -101,12 +101,6 @@ extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PT
|
||||
extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN;
|
||||
extern void (WINAPI *p__wine_ctrl_routine)(void *) DECLSPEC_HIDDEN;
|
||||
extern SYSTEM_DLL_INIT_BLOCK *pLdrSystemDllInitBlock DECLSPEC_HIDDEN;
|
||||
@ -763,15 +764,15 @@ index 452eb2790ab..8f85eb5ebc6 100644
|
||||
|
||||
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||
diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h
|
||||
index 9d9842b4072..4aaa20d1795 100644
|
||||
index 5b56f1f2cf1..a3eaf9a59d0 100644
|
||||
--- a/dlls/ntdll/unixlib.h
|
||||
+++ b/dlls/ntdll/unixlib.h
|
||||
@@ -26,7 +26,7 @@
|
||||
struct _DISPATCHER_CONTEXT;
|
||||
|
||||
/* increment this when you change the function table */
|
||||
-#define NTDLL_UNIXLIB_VERSION 126
|
||||
+#define NTDLL_UNIXLIB_VERSION 127
|
||||
-#define NTDLL_UNIXLIB_VERSION 129
|
||||
+#define NTDLL_UNIXLIB_VERSION 130
|
||||
|
||||
struct unix_funcs
|
||||
{
|
||||
@ -791,5 +792,5 @@ index 9d9842b4072..4aaa20d1795 100644
|
||||
double (CDECL *atan)( double d );
|
||||
double (CDECL *ceil)( double d );
|
||||
--
|
||||
2.30.2
|
||||
2.33.0
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user