Rebase against 32fb017d4a22be38ca271bf387e466e958601355.

This commit is contained in:
Zebediah Figura 2021-11-18 18:07:35 -06:00
parent 7e42d0ac1a
commit d3d93cfa0d
9 changed files with 9 additions and 1927 deletions

View File

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

View File

@ -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( &timespec, timeout );
- ret = futex_wait( futex, val, &timespec );
- }
- 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

View File

@ -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, &timespec ) == -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

View File

@ -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( &timespec, timeout );
- ret = futex_wait( futex, aligned_value, &timespec );
- }
- 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

View File

@ -1 +0,0 @@
Fixes: [50292] Process-local synchronization objects use private interfaces into the Unix library

View File

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

View File

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

View File

@ -1 +1 @@
161d61481f5d5ab8ee0b6237853af830e992afb1
32fb017d4a22be38ca271bf387e466e958601355