From d3d93cfa0d0da0799c876653ec8b852baa87ea9d Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 18 Nov 2021 18:07:35 -0600 Subject: [PATCH] Rebase against 32fb017d4a22be38ca271bf387e466e958601355. --- ...thread-ID-alerts-using-Mach-semaphor.patch | 149 ---- ...t-Win32-futexes-on-top-of-thread-ID-.patch | 461 ---------- ...t-the-critical-section-fast-path-on-.patch | 260 ------ ...-the-direct-futex-path-for-condition.patch | 230 ----- ...nt-SRW-locks-on-top-of-Win32-futexes.patch | 796 ------------------ .../ntdll-NtAlertThreadByThreadId/definition | 1 - patches/patchinstall.sh | 23 +- .../0001-winemac.drv-No-Flicker-patch.patch | 14 +- staging/upstream-commit | 2 +- 9 files changed, 9 insertions(+), 1927 deletions(-) delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/0010-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch delete mode 100644 patches/ntdll-NtAlertThreadByThreadId/definition diff --git a/patches/ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch b/patches/ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch deleted file mode 100644 index 7438f1ef..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0006-ntdll-Implement-thread-ID-alerts-using-Mach-semaphor.patch +++ /dev/null @@ -1,149 +0,0 @@ -From a05cafc7633a48989edd89fc99bc5d63ecd2f3bd Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -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 ---- - dlls/ntdll/unix/sync.c | 75 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 74 insertions(+), 1 deletion(-) - -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index 058262ac0ad..48960b5cb83 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 (InterlockedCompareExchange( (int *)&entry->sem, sem, NULL )) -+ semaphore_destroy( mach_task_self(), 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,10 +2387,11 @@ NTSTATUS WINAPI NtAlertThreadByThreadId( HANDLE tid ) - #endif - - return NtSetEvent( entry->event, NULL ); -+#endif - } - - --#ifdef __linux__ -+#if defined(__linux__) || defined(__APPLE__) - static LONGLONG get_absolute_timeout( const LARGE_INTEGER *timeout ) - { - LARGE_INTEGER now; -@@ -2393,6 +2414,57 @@ static LONGLONG update_timeout( ULONGLONG end ) - #endif - - -+#ifdef __APPLE__ -+ -+/*********************************************************************** -+ * NtWaitForAlertByThreadId (NTDLL.@) -+ */ -+NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEGER *timeout ) -+{ -+ union tid_alert_entry *entry = get_tid_alert_entry( NtCurrentTeb()->ClientId.UniqueThread ); -+ semaphore_t sem; -+ ULONGLONG end; -+ kern_return_t ret; -+ -+ TRACE( "%p %s\n", address, debugstr_timeout( timeout ) ); -+ -+ if (!entry) return STATUS_INVALID_CID; -+ sem = entry->sem; -+ -+ 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 -+ - /*********************************************************************** - * NtWaitForAlertByThreadId (NTDLL.@) - */ -@@ -2445,6 +2517,7 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - return status; - } - -+#endif - - #ifdef __linux__ - --- -2.30.2 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch b/patches/ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch deleted file mode 100644 index 0b080860..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0007-ntdll-Reimplement-Win32-futexes-on-top-of-thread-ID-.patch +++ /dev/null @@ -1,461 +0,0 @@ -From 4b2ad3bf49e77c6cb0e541329ac851d054e6f649 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -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 -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/sync.c | 173 ++++++++++++++++++++++++++++++++++++++- - dlls/ntdll/unix/loader.c | 3 - - dlls/ntdll/unix/sync.c | 162 ------------------------------------ - dlls/ntdll/unixlib.h | 6 +- - 4 files changed, 171 insertions(+), 173 deletions(-) - -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index bfb30661864..adc03c9ff7a 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -34,11 +34,18 @@ - #include "windef.h" - #include "winternl.h" - #include "wine/debug.h" -+#include "wine/list.h" - #include "ntdll_misc.h" - - WINE_DEFAULT_DEBUG_CHANNEL(sync); - WINE_DECLARE_DEBUG_CHANNEL(relay); - -+static const char *debugstr_timeout( const LARGE_INTEGER *timeout ) -+{ -+ if (!timeout) return "(infinite)"; -+ return wine_dbgstr_longlong( timeout->QuadPart ); -+} -+ - /****************************************************************** - * RtlRunOnceInitialize (NTDLL.@) - */ -@@ -863,13 +870,111 @@ 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. -+ */ -+ -+struct futex_entry -+{ -+ 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 void spin_wrlock( LONG *lock ) -+{ -+ while (InterlockedCompareExchange( lock, -1, 0 )) -+ YieldProcessor(); -+} -+ -+static void spin_wrunlock( LONG *lock ) -+{ -+ InterlockedExchange( lock, 0 ); -+} -+ -+static BOOL compare_addr( const void *addr, const void *cmp, SIZE_T size ) -+{ -+ switch (size) -+ { -+ case 1: -+ return (*(const UCHAR *)addr == *(const UCHAR *)cmp); -+ case 2: -+ return (*(const USHORT *)addr == *(const USHORT *)cmp); -+ case 4: -+ return (*(const ULONG *)addr == *(const ULONG *)cmp); -+ case 8: -+ return (*(const ULONG64 *)addr == *(const ULONG64 *)cmp); -+ } -+ -+ return FALSE; -+} -+ - /*********************************************************************** - * RtlWaitOnAddress (NTDLL.@) - */ - NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size, - const LARGE_INTEGER *timeout ) - { -- return unix_funcs->RtlWaitOnAddress( addr, cmp, size, timeout ); -+ 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 )); -+ -+ if (size != 1 && size != 2 && size != 4 && size != 8) -+ return STATUS_INVALID_PARAMETER; -+ -+ entry.addr = addr; -+ entry.tid = GetCurrentThreadId(); -+ -+ spin_wrlock( &queue->lock ); -+ -+ if (!compare_addr( addr, cmp, size )) -+ { -+ spin_wrunlock( &queue->lock ); -+ return STATUS_SUCCESS; -+ } -+ -+ if (!queue->queue.next) -+ list_init( &queue->queue ); -+ list_add_tail( &queue->queue, &entry.entry ); -+ -+ spin_wrunlock( &queue->lock ); -+ -+ ret = NtWaitForAlertByThreadId( NULL, timeout ); -+ -+ 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); -+ -+ if (ret == STATUS_ALERTED) ret = STATUS_SUCCESS; -+ return ret; - } - - /*********************************************************************** -@@ -877,7 +982,37 @@ NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size - */ - void WINAPI RtlWakeAddressAll( const void *addr ) - { -- return unix_funcs->RtlWakeAddressAll( addr ); -+ struct futex_queue *queue = get_futex_queue( addr ); -+ unsigned int count = 0, i; -+ struct futex_entry *entry; -+ DWORD tids[256]; -+ -+ TRACE("%p\n", addr); -+ -+ if (!addr) return; -+ -+ spin_wrlock( &queue->lock ); -+ -+ if (!queue->queue.next) -+ list_init(&queue->queue); -+ -+ LIST_FOR_EACH_ENTRY( entry, &queue->queue, struct futex_entry, entry ) -+ { -+ if (entry->addr == addr) -+ { -+ /* 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] ); - } - - /*********************************************************************** -@@ -885,5 +1020,37 @@ void WINAPI RtlWakeAddressAll( const void *addr ) - */ - void WINAPI RtlWakeAddressSingle( const void *addr ) - { -- return unix_funcs->RtlWakeAddressSingle( addr ); -+ struct futex_queue *queue = get_futex_queue( addr ); -+ struct futex_entry *entry; -+ DWORD tid = 0; -+ -+ TRACE("%p\n", addr); -+ -+ if (!addr) return; -+ -+ spin_wrlock( &queue->lock ); -+ -+ if (!queue->queue.next) -+ list_init(&queue->queue); -+ -+ LIST_FOR_EACH_ENTRY( entry, &queue->queue, struct futex_entry, entry ) -+ { -+ if (entry->addr == addr) -+ { -+ /* 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 a411b01a389..59bc978022c 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -2146,9 +2146,6 @@ static struct unix_funcs unix_funcs = - NtCurrentTeb, - #endif - RtlGetSystemTimePrecise, -- RtlWaitOnAddress, -- RtlWakeAddressAll, -- RtlWakeAddressSingle, - fast_RtlpWaitForCriticalSection, - fast_RtlpUnWaitCriticalSection, - fast_RtlDeleteCriticalSection, -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index ce78c11fd4b..c37dbc5e96e 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -74,10 +74,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(sync); - - HANDLE keyed_event = 0; - --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)"; -@@ -187,24 +183,6 @@ static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGE - #endif - - --static BOOL compare_addr( const void *addr, const void *cmp, SIZE_T size ) --{ -- switch (size) -- { -- case 1: -- return (*(const UCHAR *)addr == *(const UCHAR *)cmp); -- case 2: -- return (*(const USHORT *)addr == *(const USHORT *)cmp); -- case 4: -- return (*(const ULONG *)addr == *(const ULONG *)cmp); -- case 8: -- return (*(const ULONG64 *)addr == *(const ULONG64 *)cmp); -- } -- -- return FALSE; --} -- -- - /* 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 ) -@@ -3035,71 +3013,6 @@ NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, - return STATUS_SUCCESS; - } - -- --/* We can't map addresses to futex directly, because an application can wait on -- * 8 bytes, and we can't pass all 8 as the compare value to futex(). Instead we -- * map all addresses to a small fixed table of futexes. This may result in -- * spurious wakes, but the application is already expected to handle those. */ -- --static int addr_futex_table[256]; -- --static inline int *hash_addr( const void *addr ) --{ -- ULONG_PTR val = (ULONG_PTR)addr; -- -- return &addr_futex_table[(val >> 2) & 255]; --} -- --static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T size, -- const LARGE_INTEGER *timeout ) --{ -- int *futex; -- int val; -- struct timespec timespec; -- int ret; -- -- if (!use_futexes()) -- return STATUS_NOT_IMPLEMENTED; -- -- futex = hash_addr( addr ); -- -- /* We must read the previous value of the futex before checking the value -- * of the address being waited on. That way, if we receive a wake between -- * now and waiting on the futex, we know that val will have changed. -- * Use an atomic load so that memory accesses are ordered between this read -- * and the increment below. */ -- val = InterlockedCompareExchange( futex, 0, 0 ); -- if (!compare_addr( addr, cmp, size )) -- return STATUS_SUCCESS; -- -- if (timeout) -- { -- timespec_from_timeout( ×pec, timeout ); -- ret = futex_wait( futex, val, ×pec ); -- } -- else -- ret = futex_wait( futex, val, NULL ); -- -- if (ret == -1 && errno == ETIMEDOUT) -- return STATUS_TIMEOUT; -- return STATUS_SUCCESS; --} -- --static inline NTSTATUS fast_wake_addr( const void *addr ) --{ -- int *futex; -- -- if (!use_futexes()) -- return STATUS_NOT_IMPLEMENTED; -- -- futex = hash_addr( addr ); -- -- InterlockedIncrement( futex ); -- -- futex_wake( futex, INT_MAX ); -- return STATUS_SUCCESS; --} -- - #else - - NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) -@@ -3142,79 +3055,4 @@ NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value - return STATUS_NOT_IMPLEMENTED; - } - --static inline NTSTATUS fast_wait_addr( const void *addr, const void *cmp, SIZE_T size, -- const LARGE_INTEGER *timeout ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --static inline NTSTATUS fast_wake_addr( const void *addr ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- - #endif -- -- --/*********************************************************************** -- * RtlWaitOnAddress (NTDLL.@) -- */ --NTSTATUS WINAPI RtlWaitOnAddress( const void *addr, const void *cmp, SIZE_T size, -- const LARGE_INTEGER *timeout ) --{ -- select_op_t select_op; -- NTSTATUS ret; -- timeout_t abs_timeout = timeout ? timeout->QuadPart : TIMEOUT_INFINITE; -- -- if (size != 1 && size != 2 && size != 4 && size != 8) -- return STATUS_INVALID_PARAMETER; -- -- if ((ret = fast_wait_addr( addr, cmp, size, timeout )) != STATUS_NOT_IMPLEMENTED) -- return ret; -- -- mutex_lock( &addr_mutex ); -- if (!compare_addr( addr, cmp, size )) -- { -- mutex_unlock( &addr_mutex ); -- return STATUS_SUCCESS; -- } -- -- if (abs_timeout < 0) -- { -- LARGE_INTEGER now; -- -- NtQueryPerformanceCounter( &now, NULL ); -- abs_timeout -= now.QuadPart; -- } -- -- select_op.keyed_event.op = SELECT_KEYED_EVENT_WAIT; -- select_op.keyed_event.handle = wine_server_obj_handle( keyed_event ); -- select_op.keyed_event.key = wine_server_client_ptr( addr ); -- -- return server_select( &select_op, sizeof(select_op.keyed_event), SELECT_INTERRUPTIBLE, -- abs_timeout, NULL, &addr_mutex, NULL ); --} -- --/*********************************************************************** -- * RtlWakeAddressAll (NTDLL.@) -- */ --void WINAPI RtlWakeAddressAll( const void *addr ) --{ -- if (fast_wake_addr( addr ) != STATUS_NOT_IMPLEMENTED) return; -- -- mutex_lock( &addr_mutex ); -- while (NtReleaseKeyedEvent( 0, addr, 0, &zero_timeout ) == STATUS_SUCCESS) {} -- mutex_unlock( &addr_mutex ); --} -- --/*********************************************************************** -- * RtlWakeAddressSingle (NTDLL.@) -- */ --void WINAPI RtlWakeAddressSingle( const void *addr ) --{ -- if (fast_wake_addr( addr ) != STATUS_NOT_IMPLEMENTED) return; -- -- mutex_lock( &addr_mutex ); -- NtReleaseKeyedEvent( 0, addr, 0, &zero_timeout ); -- mutex_unlock( &addr_mutex ); --} -diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h -index 62030d91cdb..ded05c40e17 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 - { -@@ -37,10 +37,6 @@ struct unix_funcs - - /* other Win32 API functions */ - LONGLONG (WINAPI *RtlGetSystemTimePrecise)(void); -- NTSTATUS (WINAPI *RtlWaitOnAddress)( const void *addr, const void *cmp, SIZE_T size, -- const LARGE_INTEGER *timeout ); -- void (WINAPI *RtlWakeAddressAll)( const void *addr ); -- void (WINAPI *RtlWakeAddressSingle)( const void *addr ); - - /* fast locks */ - NTSTATUS (CDECL *fast_RtlpWaitForCriticalSection)( RTL_CRITICAL_SECTION *crit, int timeout ); --- -2.33.0 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch b/patches/ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch deleted file mode 100644 index aad56495..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0009-ntdll-Reimplement-the-critical-section-fast-path-on-.patch +++ /dev/null @@ -1,260 +0,0 @@ -From 628256e87f979280f1251b1a90a0ac25a0469e6c Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -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 -Signed-off-by: Zebediah Figura ---- - 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 | 5 +- - 5 files changed, 24 insertions(+), 132 deletions(-) - -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index db68a466d8a..3a47679bb60 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -172,19 +172,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit ) - - static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout ) - { -- NTSTATUS ret; -+ LARGE_INTEGER time = {.QuadPart = timeout * (LONGLONG)-10000000}; - - /* debug info is cleared by MakeCriticalSectionGlobal */ -- if (!crit_section_has_debuginfo( crit ) || -- ((ret = unix_funcs->fast_RtlpWaitForCriticalSection( crit, timeout )) == STATUS_NOT_IMPLEMENTED)) -+ if (!crit_section_has_debuginfo( crit )) - { - HANDLE sem = get_semaphore( crit ); -- LARGE_INTEGER time; -- -- time.QuadPart = timeout * (LONGLONG)-10000000; -- ret = NtWaitForSingleObject( sem, FALSE, &time ); -+ return NtWaitForSingleObject( sem, FALSE, &time ); -+ } -+ else -+ { -+ int *lock = (int *)&crit->LockSemaphore; -+ while (!InterlockedCompareExchange( lock, 0, 1 )) -+ { -+ static const int zero; -+ /* this may wait longer than specified in case of multiple wake-ups */ -+ if (RtlWaitOnAddress( lock, &zero, sizeof(int), &time ) == STATUS_TIMEOUT) -+ return STATUS_TIMEOUT; -+ } -+ return STATUS_WAIT_0; - } -- return ret; - } - - /****************************************************************************** -@@ -274,8 +281,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) - RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo ); - crit->DebugInfo = NULL; - } -- if (unix_funcs->fast_RtlDeleteCriticalSection( crit ) == STATUS_NOT_IMPLEMENTED) -- NtClose( crit->LockSemaphore ); - } - else NtClose( crit->LockSemaphore ); - crit->LockSemaphore = 0; -@@ -351,12 +356,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) - NTSTATUS ret; - - /* debug info is cleared by MakeCriticalSectionGlobal */ -- if (!crit_section_has_debuginfo( crit ) || -- ((ret = unix_funcs->fast_RtlpUnWaitCriticalSection( crit )) == STATUS_NOT_IMPLEMENTED)) -+ if (!crit_section_has_debuginfo( crit )) - { - HANDLE sem = get_semaphore( crit ); - ret = NtReleaseSemaphore( sem, 1, NULL ); - } -+ else -+ { -+ int *lock = (int *)&crit->LockSemaphore; -+ InterlockedExchange( lock, 1 ); -+ RtlWakeAddressSingle( lock ); -+ ret = STATUS_SUCCESS; -+ } - if (ret) RtlRaiseStatus( ret ); - return ret; - } -diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c -index 05ae264297a..1dbcc0d7a7b 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -2145,9 +2145,6 @@ static struct unix_funcs unix_funcs = - NtCurrentTeb, - #endif - RtlGetSystemTimePrecise, -- fast_RtlpWaitForCriticalSection, -- fast_RtlpUnWaitCriticalSection, -- fast_RtlDeleteCriticalSection, - fast_RtlTryAcquireSRWLockExclusive, - fast_RtlAcquireSRWLockExclusive, - fast_RtlTryAcquireSRWLockShared, -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index 47a0a03b45f..12df0c90d73 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -2550,115 +2550,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - - #endif - --#ifdef __linux__ -- --NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) --{ -- int val; -- struct timespec timespec; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- timespec.tv_sec = timeout; -- timespec.tv_nsec = 0; -- while ((val = InterlockedCompareExchange( (int *)&crit->LockSemaphore, 0, 1 )) != 1) -- { -- /* note: this may wait longer than specified in case of signals or */ -- /* multiple wake-ups, but that shouldn't be a problem */ -- if (futex_wait( (int *)&crit->LockSemaphore, val, ×pec ) == -1 && errno == ETIMEDOUT) -- return STATUS_TIMEOUT; -- } -- return STATUS_WAIT_0; --} -- --NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- *(int *)&crit->LockSemaphore = 1; -- futex_wake( (int *)&crit->LockSemaphore, 1 ); -- return STATUS_SUCCESS; --} -- --NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- return STATUS_SUCCESS; --} -- --#elif defined(__APPLE__) -- --static inline semaphore_t get_mach_semaphore( RTL_CRITICAL_SECTION *crit ) --{ -- semaphore_t ret = *(int *)&crit->LockSemaphore; -- if (!ret) -- { -- semaphore_t sem; -- if (semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, 0 )) return 0; -- if (!(ret = InterlockedCompareExchange( (int *)&crit->LockSemaphore, sem, 0 ))) -- ret = sem; -- else -- semaphore_destroy( mach_task_self(), sem ); /* somebody beat us to it */ -- } -- return ret; --} -- --NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) --{ -- mach_timespec_t timespec; -- semaphore_t sem = get_mach_semaphore( crit ); -- -- timespec.tv_sec = timeout; -- timespec.tv_nsec = 0; -- for (;;) -- { -- switch( semaphore_timedwait( sem, timespec )) -- { -- case KERN_SUCCESS: -- return STATUS_WAIT_0; -- case KERN_ABORTED: -- continue; /* got a signal, restart */ -- case KERN_OPERATION_TIMED_OUT: -- return STATUS_TIMEOUT; -- default: -- return STATUS_INVALID_HANDLE; -- } -- } --} -- --NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- semaphore_t sem = get_mach_semaphore( crit ); -- semaphore_signal( sem ); -- return STATUS_SUCCESS; --} -- --NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- semaphore_destroy( mach_task_self(), *(int *)&crit->LockSemaphore ); -- return STATUS_SUCCESS; --} -- --#else /* __APPLE__ */ -- --NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --#endif -- -- - #ifdef __linux__ - - /* Futex-based SRW lock implementation: -diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h -index 641de0c465f..d44a9e128ff 100644 ---- a/dlls/ntdll/unix/unix_private.h -+++ b/dlls/ntdll/unix/unix_private.h -@@ -100,10 +100,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; -- --extern NTSTATUS CDECL fast_RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit, int timeout ) DECLSPEC_HIDDEN; --extern NTSTATUS CDECL fast_RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; --extern NTSTATUS CDECL fast_RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) DECLSPEC_HIDDEN; - extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN; - 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 ded05c40e17..535f76a647e 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 129 -+#define NTDLL_UNIXLIB_VERSION 130 - - struct unix_funcs - { -@@ -39,9 +39,6 @@ struct unix_funcs - LONGLONG (WINAPI *RtlGetSystemTimePrecise)(void); - - /* fast locks */ -- NTSTATUS (CDECL *fast_RtlpWaitForCriticalSection)( RTL_CRITICAL_SECTION *crit, int timeout ); -- NTSTATUS (CDECL *fast_RtlpUnWaitCriticalSection)( RTL_CRITICAL_SECTION *crit ); -- NTSTATUS (CDECL *fast_RtlDeleteCriticalSection)( RTL_CRITICAL_SECTION *crit ); - NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockExclusive)( RTL_SRWLOCK *lock ); - NTSTATUS (CDECL *fast_RtlAcquireSRWLockExclusive)( RTL_SRWLOCK *lock ); - NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockShared)( RTL_SRWLOCK *lock ); --- -2.33.0 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0010-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch b/patches/ntdll-NtAlertThreadByThreadId/0010-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch deleted file mode 100644 index 0a72ed0f..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0010-ntdll-Get-rid-of-the-direct-futex-path-for-condition.patch +++ /dev/null @@ -1,230 +0,0 @@ -From c8044d65c40d67569c0fdbc26ce69c52b0fd3595 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -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 -Signed-off-by: Zebediah Figura ---- - 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 | 5 +-- - 5 files changed, 9 insertions(+), 96 deletions(-) - -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 3a47679bb60..6e68d07b81b 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -792,11 +792,8 @@ void WINAPI RtlInitializeConditionVariable( RTL_CONDITION_VARIABLE *variable ) - */ - void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) - { -- if (unix_funcs->fast_RtlWakeConditionVariable( variable, 1 ) == STATUS_NOT_IMPLEMENTED) -- { -- InterlockedIncrement( (int *)&variable->Ptr ); -- RtlWakeAddressSingle( variable ); -- } -+ InterlockedIncrement( (int *)&variable->Ptr ); -+ RtlWakeAddressSingle( variable ); - } - - /*********************************************************************** -@@ -806,11 +803,8 @@ void WINAPI RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable ) - */ - void WINAPI RtlWakeAllConditionVariable( RTL_CONDITION_VARIABLE *variable ) - { -- if (unix_funcs->fast_RtlWakeConditionVariable( variable, INT_MAX ) == STATUS_NOT_IMPLEMENTED) -- { -- InterlockedIncrement( (int *)&variable->Ptr ); -- RtlWakeAddressAll( variable ); -- } -+ InterlockedIncrement( (int *)&variable->Ptr ); -+ RtlWakeAddressAll( 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 ) - { -- const void *value = variable->Ptr; -+ int value = *(int *)&variable->Ptr; - NTSTATUS status; - - RtlLeaveCriticalSection( crit ); -- if ((status = unix_funcs->fast_wait_cv( variable, value, timeout )) == STATUS_NOT_IMPLEMENTED) -- status = RtlWaitOnAddress( &variable->Ptr, &value, sizeof(value), timeout ); -+ status = RtlWaitOnAddress( &variable->Ptr, &value, sizeof(value), timeout ); - RtlEnterCriticalSection( crit ); - return status; - } -@@ -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 ) - { -- const void *value = variable->Ptr; -+ int value = *(int *)&variable->Ptr; - NTSTATUS status; - - if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) -@@ -871,8 +864,7 @@ NTSTATUS WINAPI RtlSleepConditionVariableSRW( RTL_CONDITION_VARIABLE *variable, - else - RtlReleaseSRWLockExclusive( lock ); - -- if ((status = unix_funcs->fast_wait_cv( variable, value, timeout )) == STATUS_NOT_IMPLEMENTED) -- status = RtlWaitOnAddress( variable, &value, sizeof(value), timeout ); -+ status = RtlWaitOnAddress( &variable->Ptr, &value, sizeof(value), timeout ); - - if (flags & RTL_CONDITION_VARIABLE_LOCKMODE_SHARED) - RtlAcquireSRWLockShared( lock ); -diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c -index 1dbcc0d7a7b..32aa7267423 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -2151,8 +2151,6 @@ static struct unix_funcs unix_funcs = - fast_RtlAcquireSRWLockShared, - fast_RtlReleaseSRWLockExclusive, - fast_RtlReleaseSRWLockShared, -- fast_RtlWakeConditionVariable, -- fast_wait_cv, - load_so_dll, - init_builtin_dll, - init_unix_lib, -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index 12df0c90d73..7a2466f5fa3 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -162,23 +162,6 @@ static int *get_futex(void **ptr) - return NULL; - } - --static void timespec_from_timeout( struct timespec *timespec, const LARGE_INTEGER *timeout ) --{ -- LARGE_INTEGER now; -- timeout_t diff; -- -- if (timeout->QuadPart > 0) -- { -- NtQuerySystemTime( &now ); -- diff = timeout->QuadPart - now.QuadPart; -- } -- else -- diff = -timeout->QuadPart; -- -- timespec->tv_sec = diff / TICKSPERSEC; -- timespec->tv_nsec = (diff % TICKSPERSEC) * 100; --} -- - #endif - - -@@ -2802,50 +2785,6 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) - return STATUS_SUCCESS; - } - --NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout ) --{ -- const char *value_ptr; -- int aligned_value, *futex; -- struct timespec timespec; -- int ret; -- -- if (!use_futexes()) -- return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &variable->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- value_ptr = (const char *)&value; -- value_ptr += ((ULONG_PTR)futex) - ((ULONG_PTR)&variable->Ptr); -- aligned_value = *(int *)value_ptr; -- -- if (timeout && timeout->QuadPart != TIMEOUT_INFINITE) -- { -- timespec_from_timeout( ×pec, timeout ); -- ret = futex_wait( futex, aligned_value, ×pec ); -- } -- else -- ret = futex_wait( futex, aligned_value, NULL ); -- -- if (ret == -1 && errno == ETIMEDOUT) -- return STATUS_TIMEOUT; -- return STATUS_WAIT_0; --} -- --NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count ) --{ -- int *futex; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &variable->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- InterlockedIncrement( futex ); -- futex_wake( futex, count ); -- return STATUS_SUCCESS; --} -- - #else - - NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) -@@ -2878,14 +2817,4 @@ NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) - return STATUS_NOT_IMPLEMENTED; - } - --NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- - #endif -diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h -index d44a9e128ff..61f37d4b22f 100644 ---- a/dlls/ntdll/unix/unix_private.h -+++ b/dlls/ntdll/unix/unix_private.h -@@ -106,10 +106,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; --extern NTSTATUS CDECL fast_RtlWakeConditionVariable( RTL_CONDITION_VARIABLE *variable, int count ) DECLSPEC_HIDDEN; - extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN; --extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, -- const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN; - - 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 535f76a647e..a271bb05da9 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 130 -+#define NTDLL_UNIXLIB_VERSION 131 - - struct unix_funcs - { -@@ -45,9 +45,6 @@ struct unix_funcs - NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock ); - NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock ); - NTSTATUS (CDECL *fast_RtlReleaseSRWLockShared)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlWakeConditionVariable)( RTL_CONDITION_VARIABLE *variable, int count ); -- NTSTATUS (CDECL *fast_wait_cv)( RTL_CONDITION_VARIABLE *variable, const void *value, -- const LARGE_INTEGER *timeout ); - - /* loader functions */ - NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); --- -2.33.0 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch b/patches/ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch deleted file mode 100644 index 1101257f..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/0011-ntdll-Reimplement-SRW-locks-on-top-of-Win32-futexes.patch +++ /dev/null @@ -1,796 +0,0 @@ -From 2c2b45abf167701ed4736fcc7530b9927ff67ee5 Mon Sep 17 00:00:00 2001 -From: Zebediah Figura -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 -Signed-off-by: Zebediah Figura ---- - dlls/ntdll/sync.c | 313 +++++++++++++++------------------ - dlls/ntdll/unix/loader.c | 6 - - dlls/ntdll/unix/sync.c | 308 -------------------------------- - dlls/ntdll/unix/unix_private.h | 6 - - dlls/ntdll/unixlib.h | 10 +- - 5 files changed, 142 insertions(+), 501 deletions(-) - -diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c -index 6e68d07b81b..e380f3e4e93 100644 ---- a/dlls/ntdll/sync.c -+++ b/dlls/ntdll/sync.c -@@ -503,127 +503,24 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu - return RtlRunOnceComplete( once, 0, context ? *context : NULL ); - } - -- --/* SRW locks implementation -- * -- * The memory layout used by the lock is: -- * -- * 32 31 16 0 -- * ________________ ________________ -- * | X| #exclusive | #shared | -- * ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ -- * Since there is no space left for a separate counter of shared access -- * threads inside the locked section the #shared field is used for multiple -- * purposes. The following table lists all possible states the lock can be -- * in, notation: [X, #exclusive, #shared]: -- * -- * [0, 0, N] -> locked by N shared access threads, if N=0 it's unlocked -- * [0, >=1, >=1] -> threads are requesting exclusive locks, but there are -- * still shared access threads inside. #shared should not be incremented -- * anymore! -- * [1, >=1, >=0] -> lock is owned by an exclusive thread and the #shared -- * counter can be used again to count the number of threads waiting in the -- * queue for shared access. -- * -- * the following states are invalid and will never occur: -- * [0, >=1, 0], [1, 0, >=0] -- * -- * The main problem arising from the fact that we have no separate counter -- * of shared access threads inside the locked section is that in the state -- * [0, >=1, >=1] above we cannot add additional waiting threads to the -- * shared access queue - it wouldn't be possible to distinguish waiting -- * threads and those that are still inside. To solve this problem the lock -- * uses the following approach: a thread that isn't able to allocate a -- * shared lock just uses the exclusive queue instead. As soon as the thread -- * is woken up it is in the state [1, >=1, >=0]. In this state it's again -- * possible to use the shared access queue. The thread atomically moves -- * itself to the shared access queue and releases the exclusive lock, so -- * that the "real" exclusive access threads have a chance. As soon as they -- * are all ready the shared access threads are processed. -- */ -- --#define SRWLOCK_MASK_IN_EXCLUSIVE 0x80000000 --#define SRWLOCK_MASK_EXCLUSIVE_QUEUE 0x7fff0000 --#define SRWLOCK_MASK_SHARED_QUEUE 0x0000ffff --#define SRWLOCK_RES_EXCLUSIVE 0x00010000 --#define SRWLOCK_RES_SHARED 0x00000001 -- --#ifdef WORDS_BIGENDIAN --#define srwlock_key_exclusive(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 1) & ~1)) --#define srwlock_key_shared(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 3) & ~1)) --#else --#define srwlock_key_exclusive(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 3) & ~1)) --#define srwlock_key_shared(lock) ((void *)(((ULONG_PTR)&lock->Ptr + 1) & ~1)) --#endif -- --static inline void srwlock_check_invalid( unsigned int val ) -+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; -- /* Atomically modifies the value of *dest by adding incr. If the shared -- * queue is empty and there are threads waiting for exclusive access, then -- * sets the mark SRWLOCK_MASK_IN_EXCLUSIVE to signal other threads that -- * they are allowed again to use the shared queue counter. */ -- for (val = *dest;; val = tmp) -- { -- tmp = val + incr; -- srwlock_check_invalid( tmp ); -- if ((tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(tmp & SRWLOCK_MASK_SHARED_QUEUE)) -- tmp |= SRWLOCK_MASK_IN_EXCLUSIVE; -- if ((tmp = InterlockedCompareExchange( (int *)dest, tmp, val )) == val) -- break; -- } -- return val; --} -- --static inline unsigned int srwlock_unlock_exclusive( unsigned int *dest, int incr ) --{ -- unsigned int val, tmp; -- /* Atomically modifies the value of *dest by adding incr. If the queue of -- * threads waiting for exclusive access is empty, then remove the -- * SRWLOCK_MASK_IN_EXCLUSIVE flag (only the shared queue counter will -- * remain). */ -- for (val = *dest;; val = tmp) -- { -- tmp = val + incr; -- srwlock_check_invalid( tmp ); -- if (!(tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE)) -- tmp &= SRWLOCK_MASK_SHARED_QUEUE; -- if ((tmp = InterlockedCompareExchange( (int *)dest, tmp, val )) == val) -- break; -- } -- return val; --} -- --static inline void srwlock_leave_exclusive( RTL_SRWLOCK *lock, unsigned int val ) --{ -- /* Used when a thread leaves an exclusive section. If there are other -- * exclusive access threads they are processed first, followed by -- * the shared waiters. */ -- if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) -- NtReleaseKeyedEvent( 0, srwlock_key_exclusive(lock), FALSE, NULL ); -- else -- { -- val &= SRWLOCK_MASK_SHARED_QUEUE; /* remove SRWLOCK_MASK_IN_EXCLUSIVE */ -- while (val--) -- NtReleaseKeyedEvent( 0, srwlock_key_shared(lock), FALSE, NULL ); -- } --} -- --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 -- * has left. */ -- if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_SHARED_QUEUE)) -- NtReleaseKeyedEvent( 0, srwlock_key_exclusive(lock), FALSE, NULL ); --} -+ /* Number of shared owners, or -1 if owned exclusive. -+ * -+ * Sadly Windows has no equivalent to FUTEX_WAIT_BITSET, so in order to wake -+ * up *only* exclusive or *only* shared waiters (and thus avoid spurious -+ * wakeups), we need to wait on two different addresses. -+ * RtlAcquireSRWLockShared() needs to know the values of "exclusive_waiters" -+ * and "owners", but RtlAcquireSRWLockExclusive() only needs to know the -+ * value of "owners", so the former can wait on the entire structure, and -+ * the latter waits only on the "owners" member. Note then that "owners" -+ * must not be the first element in the structure. -+ */ -+ short owners; -+}; -+C_ASSERT( sizeof(struct srw_lock) == 4 ); - - /*********************************************************************** - * RtlInitializeSRWLock (NTDLL.@) -@@ -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 (;;) -+ { -+ union { struct srw_lock s; LONG l; } old, new; -+ BOOL wait; -+ -+ do -+ { -+ old.s = *u.s; -+ new.s = old.s; -+ -+ if (!old.s.owners) -+ { -+ /* Not locked exclusive or shared. We can try to grab it. */ -+ new.s.owners = -1; -+ --new.s.exclusive_waiters; -+ wait = FALSE; -+ } -+ else -+ { -+ wait = TRUE; -+ } -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ if (!wait) return; -+ RtlWaitOnAddress( &u.s->owners, &new.s.owners, sizeof(short), NULL ); -+ } - } - - /*********************************************************************** -@@ -666,34 +588,34 @@ void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) - */ - void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) - { -- unsigned int val, tmp; -+ 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) -+ for (;;) - { -- if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_IN_EXCLUSIVE)) -- tmp = val + SRWLOCK_RES_EXCLUSIVE; -- else -- tmp = val + SRWLOCK_RES_SHARED; -- if ((tmp = InterlockedCompareExchange( (int *)&lock->Ptr, tmp, val )) == val) -- break; -- } -+ union { struct srw_lock s; LONG l; } old, new; -+ BOOL wait; - -- /* Drop exclusive access again and instead requeue for shared access. */ -- if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_IN_EXCLUSIVE)) -- { -- NtWaitForKeyedEvent( 0, srwlock_key_exclusive(lock), FALSE, NULL ); -- val = srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr, (SRWLOCK_RES_SHARED -- - SRWLOCK_RES_EXCLUSIVE) ) - SRWLOCK_RES_EXCLUSIVE; -- srwlock_leave_exclusive( lock, val ); -- } -+ do -+ { -+ old.s = *u.s; -+ new = old; - -- if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) -- NtWaitForKeyedEvent( 0, srwlock_key_shared(lock), FALSE, NULL ); -+ if (old.s.owners != -1 && !old.s.exclusive_waiters) -+ { -+ /* Not locked exclusive, and no exclusive waiters. -+ * We can try to grab it. */ -+ ++new.s.owners; -+ wait = FALSE; -+ } -+ else -+ { -+ wait = TRUE; -+ } -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ if (!wait) return; -+ RtlWaitOnAddress( u.s, &new.s, sizeof(struct srw_lock), NULL ); -+ } - } - - /*********************************************************************** -@@ -701,11 +623,23 @@ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) - */ - void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) - { -- if (unix_funcs->fast_RtlReleaseSRWLockExclusive( lock ) != STATUS_NOT_IMPLEMENTED) -- 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); -+ -+ new.s.owners = 0; -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ if (new.s.exclusive_waiters) -+ RtlWakeAddressSingle( &u.s->owners ); -+ else -+ RtlWakeAddressAll( u.s ); - } - - /*********************************************************************** -@@ -713,11 +647,22 @@ void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) - */ - void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) - { -- if (unix_funcs->fast_RtlReleaseSRWLockShared( lock ) != STATUS_NOT_IMPLEMENTED) -- 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; -+ -+ 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); -+ -+ --new.s.owners; -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ if (!new.s.owners) -+ RtlWakeAddressSingle( &u.s->owners ); - } - - /*********************************************************************** -@@ -729,13 +674,28 @@ void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) - */ - BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) - { -- NTSTATUS ret; -+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock }; -+ union { struct srw_lock s; LONG l; } old, new; -+ BOOLEAN ret; - -- if ((ret = unix_funcs->fast_RtlTryAcquireSRWLockExclusive( lock )) != STATUS_NOT_IMPLEMENTED) -- return (ret == STATUS_SUCCESS); -+ do -+ { -+ 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. */ -+ new.s.owners = -1; -+ ret = TRUE; -+ } -+ else -+ { -+ ret = FALSE; -+ } -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ return ret; - } - - /*********************************************************************** -@@ -743,20 +703,29 @@ BOOLEAN WINAPI RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) - */ - BOOLEAN WINAPI RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) - { -- unsigned int val, tmp; -- NTSTATUS ret; -+ union { RTL_SRWLOCK *rtl; struct srw_lock *s; LONG *l; } u = { lock }; -+ union { struct srw_lock s; LONG l; } old, new; -+ BOOLEAN ret; - -- if ((ret = unix_funcs->fast_RtlTryAcquireSRWLockShared( lock )) != STATUS_NOT_IMPLEMENTED) -- return (ret == STATUS_SUCCESS); -- -- for (val = *(unsigned int *)&lock->Ptr;; val = tmp) -+ do - { -- if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) -- return FALSE; -- if ((tmp = InterlockedCompareExchange( (int *)&lock->Ptr, val + SRWLOCK_RES_SHARED, val )) == val) -- break; -- } -- return TRUE; -+ old.s = *u.s; -+ new.s = old.s; -+ -+ if (old.s.owners != -1 && !old.s.exclusive_waiters) -+ { -+ /* Not locked exclusive, and no exclusive waiters. -+ * We can try to grab it. */ -+ ++new.s.owners; -+ ret = TRUE; -+ } -+ else -+ { -+ ret = FALSE; -+ } -+ } while (InterlockedCompareExchange( u.l, new.l, old.l ) != old.l); -+ -+ return ret; - } - - /*********************************************************************** -diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c -index 32aa7267423..3d26da194e4 100644 ---- a/dlls/ntdll/unix/loader.c -+++ b/dlls/ntdll/unix/loader.c -@@ -2145,12 +2145,6 @@ static struct unix_funcs unix_funcs = - NtCurrentTeb, - #endif - RtlGetSystemTimePrecise, -- fast_RtlTryAcquireSRWLockExclusive, -- fast_RtlAcquireSRWLockExclusive, -- fast_RtlTryAcquireSRWLockShared, -- fast_RtlAcquireSRWLockShared, -- fast_RtlReleaseSRWLockExclusive, -- fast_RtlReleaseSRWLockShared, - load_so_dll, - init_builtin_dll, - init_unix_lib, -diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c -index 7a2466f5fa3..0065f265e42 100644 ---- a/dlls/ntdll/unix/sync.c -+++ b/dlls/ntdll/unix/sync.c -@@ -110,8 +110,6 @@ static inline ULONGLONG monotonic_counter(void) - - #define FUTEX_WAIT 0 - #define FUTEX_WAKE 1 --#define FUTEX_WAIT_BITSET 9 --#define FUTEX_WAKE_BITSET 10 - - static int futex_private = 128; - -@@ -125,16 +123,6 @@ static inline int futex_wake( const int *addr, int val ) - return syscall( __NR_futex, addr, FUTEX_WAKE | futex_private, val, NULL, 0, 0 ); - } - --static inline int futex_wait_bitset( const int *addr, int val, struct timespec *timeout, int mask ) --{ -- return syscall( __NR_futex, addr, FUTEX_WAIT_BITSET | futex_private, val, timeout, 0, mask ); --} -- --static inline int futex_wake_bitset( const int *addr, int val, int mask ) --{ -- return syscall( __NR_futex, addr, FUTEX_WAKE_BITSET | futex_private, val, NULL, 0, mask ); --} -- - static inline int use_futexes(void) - { - static int supported = -1; -@@ -152,16 +140,6 @@ static inline int use_futexes(void) - return supported; - } - --static int *get_futex(void **ptr) --{ -- if (sizeof(void *) == 8) -- return (int *)((((ULONG_PTR)ptr) + 3) & ~3); -- else if (!(((ULONG_PTR)ptr) & 3)) -- return (int *)ptr; -- else -- return NULL; --} -- - #endif - - -@@ -2532,289 +2510,3 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG - } - - #endif -- --#ifdef __linux__ -- --/* Futex-based SRW lock implementation: -- * -- * Since we can rely on the kernel to release all threads and don't need to -- * worry about NtReleaseKeyedEvent(), we can simplify the layout a bit. The -- * layout looks like this: -- * -- * 31 - Exclusive lock bit, set if the resource is owned exclusively. -- * 30-16 - Number of exclusive waiters. Unlike the fallback implementation, -- * this does not include the thread owning the lock, or shared threads -- * waiting on the lock. -- * 15 - Does this lock have any shared waiters? We use this as an -- * optimization to avoid unnecessary FUTEX_WAKE_BITSET calls when -- * releasing an exclusive lock. -- * 14-0 - Number of shared owners. Unlike the fallback implementation, this -- * does not include the number of shared threads waiting on the lock. -- * Thus the state [1, x, >=1] will never occur. -- */ -- --#define SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT 0x80000000 --#define SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK 0x7fff0000 --#define SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_INC 0x00010000 --#define SRWLOCK_FUTEX_SHARED_WAITERS_BIT 0x00008000 --#define SRWLOCK_FUTEX_SHARED_OWNERS_MASK 0x00007fff --#define SRWLOCK_FUTEX_SHARED_OWNERS_INC 0x00000001 -- --/* Futex bitmasks; these are independent from the bits in the lock itself. */ --#define SRWLOCK_FUTEX_BITSET_EXCLUSIVE 1 --#define SRWLOCK_FUTEX_BITSET_SHARED 2 -- --NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- int old, new, *futex; -- NTSTATUS ret; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- do -- { -- old = *futex; -- -- if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT) -- && !(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK)) -- { -- /* Not locked exclusive or shared. We can try to grab it. */ -- new = old | SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT; -- ret = STATUS_SUCCESS; -- } -- else -- { -- new = old; -- ret = STATUS_TIMEOUT; -- } -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- return ret; --} -- --NTSTATUS CDECL fast_RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- int old, new, *futex; -- BOOLEAN wait; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- /* Atomically increment the exclusive waiter count. */ -- do -- { -- old = *futex; -- new = old + SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_INC; -- assert(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK); -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- for (;;) -- { -- do -- { -- old = *futex; -- -- if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT) -- && !(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK)) -- { -- /* Not locked exclusive or shared. We can try to grab it. */ -- new = old | SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT; -- assert(old & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK); -- new -= SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_INC; -- wait = FALSE; -- } -- else -- { -- new = old; -- wait = TRUE; -- } -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- if (!wait) -- return STATUS_SUCCESS; -- -- futex_wait_bitset( futex, new, NULL, SRWLOCK_FUTEX_BITSET_EXCLUSIVE ); -- } -- -- return STATUS_SUCCESS; --} -- --NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) --{ -- int new, old, *futex; -- NTSTATUS ret; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- do -- { -- old = *futex; -- -- if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT) -- && !(old & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)) -- { -- /* Not locked exclusive, and no exclusive waiters. We can try to -- * grab it. */ -- new = old + SRWLOCK_FUTEX_SHARED_OWNERS_INC; -- assert(new & SRWLOCK_FUTEX_SHARED_OWNERS_MASK); -- ret = STATUS_SUCCESS; -- } -- else -- { -- new = old; -- ret = STATUS_TIMEOUT; -- } -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- return ret; --} -- --NTSTATUS CDECL fast_RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) --{ -- int old, new, *futex; -- BOOLEAN wait; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- for (;;) -- { -- do -- { -- old = *futex; -- -- if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT) -- && !(old & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)) -- { -- /* Not locked exclusive, and no exclusive waiters. We can try -- * to grab it. */ -- new = old + SRWLOCK_FUTEX_SHARED_OWNERS_INC; -- assert(new & SRWLOCK_FUTEX_SHARED_OWNERS_MASK); -- wait = FALSE; -- } -- else -- { -- new = old | SRWLOCK_FUTEX_SHARED_WAITERS_BIT; -- wait = TRUE; -- } -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- if (!wait) -- return STATUS_SUCCESS; -- -- futex_wait_bitset( futex, new, NULL, SRWLOCK_FUTEX_BITSET_SHARED ); -- } -- -- return STATUS_SUCCESS; --} -- --NTSTATUS CDECL fast_RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- int old, new, *futex; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- do -- { -- old = *futex; -- -- if (!(old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT)) -- { -- ERR("Lock %p is not owned exclusive! (%#x)\n", lock, *futex); -- return STATUS_RESOURCE_NOT_OWNED; -- } -- -- new = old & ~SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT; -- -- if (!(new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)) -- new &= ~SRWLOCK_FUTEX_SHARED_WAITERS_BIT; -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- if (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK) -- futex_wake_bitset( futex, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE ); -- else if (old & SRWLOCK_FUTEX_SHARED_WAITERS_BIT) -- futex_wake_bitset( futex, INT_MAX, SRWLOCK_FUTEX_BITSET_SHARED ); -- -- return STATUS_SUCCESS; --} -- --NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) --{ -- int old, new, *futex; -- -- if (!use_futexes()) return STATUS_NOT_IMPLEMENTED; -- -- if (!(futex = get_futex( &lock->Ptr ))) -- return STATUS_NOT_IMPLEMENTED; -- -- do -- { -- old = *futex; -- -- if (old & SRWLOCK_FUTEX_EXCLUSIVE_LOCK_BIT) -- { -- ERR("Lock %p is owned exclusive! (%#x)\n", lock, *futex); -- return STATUS_RESOURCE_NOT_OWNED; -- } -- else if (!(old & SRWLOCK_FUTEX_SHARED_OWNERS_MASK)) -- { -- ERR("Lock %p is not owned shared! (%#x)\n", lock, *futex); -- return STATUS_RESOURCE_NOT_OWNED; -- } -- -- new = old - SRWLOCK_FUTEX_SHARED_OWNERS_INC; -- } while (InterlockedCompareExchange( futex, new, old ) != old); -- -- /* Optimization: only bother waking if there are actually exclusive waiters. */ -- if (!(new & SRWLOCK_FUTEX_SHARED_OWNERS_MASK) && (new & SRWLOCK_FUTEX_EXCLUSIVE_WAITERS_MASK)) -- futex_wake_bitset( futex, 1, SRWLOCK_FUTEX_BITSET_EXCLUSIVE ); -- -- return STATUS_SUCCESS; --} -- --#else -- --NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlAcquireSRWLockShared( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --NTSTATUS CDECL fast_RtlReleaseSRWLockShared( RTL_SRWLOCK *lock ) --{ -- return STATUS_NOT_IMPLEMENTED; --} -- --#endif -diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h -index 61f37d4b22f..b499978b2fe 100644 ---- a/dlls/ntdll/unix/unix_private.h -+++ b/dlls/ntdll/unix/unix_private.h -@@ -100,12 +100,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; --extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN; --extern NTSTATUS CDECL fast_RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN; --extern NTSTATUS CDECL fast_RtlTryAcquireSRWLockShared( RTL_SRWLOCK *lock ) DECLSPEC_HIDDEN; --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; - extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN; - - 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 a271bb05da9..803b6a082bb 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 131 -+#define NTDLL_UNIXLIB_VERSION 132 - - struct unix_funcs - { -@@ -38,14 +38,6 @@ struct unix_funcs - /* other Win32 API functions */ - LONGLONG (WINAPI *RtlGetSystemTimePrecise)(void); - -- /* fast locks */ -- NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockExclusive)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlAcquireSRWLockExclusive)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlTryAcquireSRWLockShared)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlAcquireSRWLockShared)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlReleaseSRWLockExclusive)( RTL_SRWLOCK *lock ); -- NTSTATUS (CDECL *fast_RtlReleaseSRWLockShared)( RTL_SRWLOCK *lock ); -- - /* loader functions */ - NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); - void (CDECL *init_builtin_dll)( void *module ); --- -2.33.0 - diff --git a/patches/ntdll-NtAlertThreadByThreadId/definition b/patches/ntdll-NtAlertThreadByThreadId/definition deleted file mode 100644 index 928c75a7..00000000 --- a/patches/ntdll-NtAlertThreadByThreadId/definition +++ /dev/null @@ -1 +0,0 @@ -Fixes: [50292] Process-local synchronization objects use private interfaces into the Unix library diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 038e2499..11711cb2 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "161d61481f5d5ab8ee0b6237853af830e992afb1" + echo "32fb017d4a22be38ca271bf387e466e958601355" } # Show version information @@ -149,7 +149,6 @@ patch_enable_all () enable_ntdll_Hide_Wine_Exports="$1" enable_ntdll_Junction_Points="$1" enable_ntdll_Manifest_Range="$1" - enable_ntdll_NtAlertThreadByThreadId="$1" enable_ntdll_NtQueryEaFile="$1" enable_ntdll_NtQuerySection="$1" enable_ntdll_NtSetLdtEntries="$1" @@ -478,9 +477,6 @@ patch_enable () ntdll-Manifest_Range) enable_ntdll_Manifest_Range="$2" ;; - ntdll-NtAlertThreadByThreadId) - enable_ntdll_NtAlertThreadByThreadId="$2" - ;; ntdll-NtQueryEaFile) enable_ntdll_NtQueryEaFile="$2" ;; @@ -2496,23 +2492,6 @@ if test "$enable_ntdll_Manifest_Range" -eq 1; then patch_apply ntdll-Manifest_Range/0001-ntdll-Support-ISOLATIONAWARE_MANIFEST_RESOURCE_ID-ra.patch fi -# Patchset ntdll-NtAlertThreadByThreadId -# | -# | This patchset fixes the following Wine bugs: -# | * [#50292] Process-local synchronization objects use private interfaces into the Unix library -# | -# | Modified files: -# | * dlls/ntdll/sync.c, dlls/ntdll/unix/loader.c, dlls/ntdll/unix/sync.c, dlls/ntdll/unix/unix_private.h, -# | dlls/ntdll/unixlib.h -# | -if test "$enable_ntdll_NtAlertThreadByThreadId" -eq 1; then - 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/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 # | # | Modified files: diff --git a/patches/winemac.drv-no-flicker-patch/0001-winemac.drv-No-Flicker-patch.patch b/patches/winemac.drv-no-flicker-patch/0001-winemac.drv-No-Flicker-patch.patch index 66b93108..32f55eb9 100644 --- a/patches/winemac.drv-no-flicker-patch/0001-winemac.drv-No-Flicker-patch.patch +++ b/patches/winemac.drv-no-flicker-patch/0001-winemac.drv-No-Flicker-patch.patch @@ -1,4 +1,4 @@ -From b3cbf1c996a0a6f9533aa4461f77df08c123f74d Mon Sep 17 00:00:00 2001 +From 9a550439fe370711ce1a2146753aa41026d5fb2a Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Tue, 22 Jun 2021 07:56:43 +1000 Subject: [PATCH] winemac.drv: No Flicker patch @@ -10,7 +10,7 @@ Subject: [PATCH] winemac.drv: No Flicker patch 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h -index a7c0b4cac87..be119c50d48 100644 +index d73a52fa35f..f85973de13d 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -41,6 +41,7 @@ @@ -22,7 +22,7 @@ index a7c0b4cac87..be119c50d48 100644 extern const char* debugstr_cf(CFTypeRef t) DECLSPEC_HIDDEN; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c -index 203e993ee93..2e5c1329a2a 100644 +index d8d16b1f4df..09fee166a05 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -63,6 +63,7 @@ int gl_surface_mode = GL_SURFACE_IN_FRONT_OPAQUE; @@ -44,10 +44,10 @@ index 203e993ee93..2e5c1329a2a 100644 processes in the prefix. */ if (!get_config_key(hkey, NULL, "RetinaMode", buffer, sizeof(buffer))) diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c -index 9f02e93d376..f3d4e2850e7 100644 +index 33132de7415..b2c66296d9c 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c -@@ -1477,7 +1477,7 @@ static BOOL create_context(struct wgl_context *context, CGLContextObj share, uns +@@ -1465,7 +1465,7 @@ static BOOL create_context(struct wgl_context *context, CGLContextObj share, uns attribs[n++] = pf->samples; } @@ -55,7 +55,7 @@ index 9f02e93d376..f3d4e2850e7 100644 + if (force_backing_store || pf->backing_store) attribs[n++] = kCGLPFABackingStore; - #if defined(MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + if (core) -- -2.30.2 +2.33.0 diff --git a/staging/upstream-commit b/staging/upstream-commit index 3024ecc3..73eeaec4 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -161d61481f5d5ab8ee0b6237853af830e992afb1 +32fb017d4a22be38ca271bf387e466e958601355