2021-03-16 15:44:07 -07:00
|
|
|
From badd87317d22d40c86b646d03ca60e69a0258bb1 Mon Sep 17 00:00:00 2001
|
2020-12-08 18:56:56 -08:00
|
|
|
From: Zebediah Figura <z.figura12@gmail.com>
|
|
|
|
Date: Mon, 31 Aug 2020 23:38:09 -0500
|
2021-01-21 15:44:50 -08:00
|
|
|
Subject: [PATCH] ntdll: Reimplement the critical section fast path on top of
|
|
|
|
Win32 futexes.
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
|
|
|
|
---
|
|
|
|
dlls/ntdll/sync.c | 35 +++++++----
|
|
|
|
dlls/ntdll/unix/loader.c | 3 -
|
|
|
|
dlls/ntdll/unix/sync.c | 109 ---------------------------------
|
|
|
|
dlls/ntdll/unix/unix_private.h | 3 -
|
2021-02-27 15:16:06 -08:00
|
|
|
dlls/ntdll/unixlib.h | 5 +-
|
|
|
|
5 files changed, 24 insertions(+), 131 deletions(-)
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
2021-02-27 15:16:06 -08:00
|
|
|
index 09975ac3d45..97a5ce7fffa 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/sync.c
|
|
|
|
+++ b/dlls/ntdll/sync.c
|
2021-02-27 15:16:06 -08:00
|
|
|
@@ -765,19 +765,26 @@ static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
|
2020-12-08 18:56:56 -08:00
|
|
|
|
|
|
|
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 */
|
2021-02-27 15:16:06 -08:00
|
|
|
+ if (RtlWaitOnAddress( lock, &zero, sizeof(int), &time ) == STATUS_TIMEOUT)
|
2020-12-08 18:56:56 -08:00
|
|
|
+ return STATUS_TIMEOUT;
|
|
|
|
+ }
|
|
|
|
+ return STATUS_WAIT_0;
|
|
|
|
}
|
|
|
|
- return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2021-02-27 15:16:06 -08:00
|
|
|
@@ -867,8 +874,6 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
|
2020-12-08 18:56:56 -08:00
|
|
|
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;
|
2021-02-27 15:16:06 -08:00
|
|
|
@@ -944,12 +949,18 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
|
2020-12-08 18:56:56 -08:00
|
|
|
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;
|
2021-02-27 15:16:06 -08:00
|
|
|
+ InterlockedExchange( lock, 1 );
|
2020-12-08 18:56:56 -08:00
|
|
|
+ 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
|
2021-03-16 15:44:07 -07:00
|
|
|
index 10de9ce307a..ef9f160dc00 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/unix/loader.c
|
|
|
|
+++ b/dlls/ntdll/unix/loader.c
|
2021-03-16 15:44:07 -07:00
|
|
|
@@ -1552,9 +1552,6 @@ static struct unix_funcs unix_funcs =
|
2021-01-21 15:44:50 -08:00
|
|
|
#endif
|
2020-12-08 18:56:56 -08:00
|
|
|
DbgUiIssueRemoteBreakin,
|
|
|
|
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
|
2021-03-16 15:44:07 -07:00
|
|
|
index d68dfbbf6af..48bddbbcea3 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/unix/sync.c
|
|
|
|
+++ b/dlls/ntdll/unix/sync.c
|
2021-03-16 15:44:07 -07:00
|
|
|
@@ -2465,115 +2465,6 @@ NTSTATUS WINAPI NtWaitForAlertByThreadId( const void *address, const LARGE_INTEG
|
2020-12-08 18:56:56 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-#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
|
2021-03-16 15:44:07 -07:00
|
|
|
index d37dd001655..5458bf47374 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/unix/unix_private.h
|
|
|
|
+++ b/dlls/ntdll/unix/unix_private.h
|
2021-03-16 15:44:07 -07:00
|
|
|
@@ -101,9 +101,6 @@ extern void (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULON
|
2020-12-08 18:56:56 -08:00
|
|
|
extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
|
|
|
|
extern void (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN;
|
|
|
|
extern void (WINAPI *pRtlUserThreadStart)( PRTL_THREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN;
|
|
|
|
-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
|
2021-03-16 15:44:07 -07:00
|
|
|
index 7d5bfa8e249..ad2f1760ebd 100644
|
2020-12-08 18:56:56 -08:00
|
|
|
--- a/dlls/ntdll/unixlib.h
|
|
|
|
+++ b/dlls/ntdll/unixlib.h
|
2021-03-16 15:44:07 -07:00
|
|
|
@@ -37,7 +37,7 @@ enum loadorder
|
|
|
|
};
|
2021-02-27 15:16:06 -08:00
|
|
|
|
|
|
|
/* increment this when you change the function table */
|
2021-03-16 15:44:07 -07:00
|
|
|
-#define NTDLL_UNIXLIB_VERSION 119
|
|
|
|
+#define NTDLL_UNIXLIB_VERSION 120
|
2021-02-27 15:16:06 -08:00
|
|
|
|
|
|
|
struct unix_funcs
|
|
|
|
{
|
2021-03-16 15:44:07 -07:00
|
|
|
@@ -51,9 +51,6 @@ struct unix_funcs
|
2020-12-08 18:56:56 -08:00
|
|
|
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 );
|
|
|
|
--
|
2021-03-16 15:44:07 -07:00
|
|
|
2.30.1
|
2020-12-08 18:56:56 -08:00
|
|
|
|