mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Rebase against 32fb017d4a22be38ca271bf387e466e958601355.
This commit is contained in:
parent
7e42d0ac1a
commit
d3d93cfa0d
@ -1,149 +0,0 @@
|
||||
From a05cafc7633a48989edd89fc99bc5d63ecd2f3bd Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
Date: Fri, 30 Apr 2021 16:43:08 -0500
|
||||
Subject: [PATCH] ntdll: Implement thread-ID alerts using Mach semaphores on
|
||||
Mac.
|
||||
|
||||
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
||||
---
|
||||
dlls/ntdll/unix/sync.c | 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
|
||||
|
@ -1,461 +0,0 @@
|
||||
From 4b2ad3bf49e77c6cb0e541329ac851d054e6f649 Mon Sep 17 00:00:00 2001
|
||||
From: Zebediah Figura <z.figura12@gmail.com>
|
||||
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 | 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
|
||||
|
@ -1,260 +0,0 @@
|
||||
From 628256e87f979280f1251b1a90a0ac25a0469e6c 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 | 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
|
||||
|
@ -1,230 +0,0 @@
|
||||
From c8044d65c40d67569c0fdbc26ce69c52b0fd3595 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 | 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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
Fixes: [50292] Process-local synchronization objects use private interfaces into the Unix library
|
@ -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:
|
||||
|
@ -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 <ken@codeweavers.com>
|
||||
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
|
||||
|
||||
|
@ -1 +1 @@
|
||||
161d61481f5d5ab8ee0b6237853af830e992afb1
|
||||
32fb017d4a22be38ca271bf387e466e958601355
|
||||
|
Loading…
x
Reference in New Issue
Block a user