Added patch to use an inline version of Rtl{Enter,Leave}CriticalSection in some ntdll functions.

This commit is contained in:
Sebastian Lackner 2017-08-06 06:14:42 +02:00
parent d364296484
commit 8f9cc5e01c
5 changed files with 826 additions and 0 deletions

View File

@ -0,0 +1,90 @@
From 1ac9a6a07169a6d9dc3583c332513586fa2e8a54 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:37:47 +0200
Subject: include: Move interlocked_inc/dec to port.h.
---
dlls/ntdll/critsection.c | 10 ----------
dlls/ntdll/threadpool.c | 10 ----------
include/wine/port.h | 14 +++++++++++++-
3 files changed, 13 insertions(+), 21 deletions(-)
diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index e405b08a5a7..a4bd463bd25 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -40,16 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
WINE_DECLARE_DEBUG_CHANNEL(relay);
-static inline LONG interlocked_inc( PLONG dest )
-{
- return interlocked_xchg_add( dest, 1 ) + 1;
-}
-
-static inline LONG interlocked_dec( PLONG dest )
-{
- return interlocked_xchg_add( dest, -1 ) - 1;
-}
-
static inline void small_pause(void)
{
#ifdef __i386__
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 6063d51d9f9..b723e6f66f8 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -331,16 +331,6 @@ static void tp_object_prepare_shutdown( struct threadpool_object *object );
static BOOL tp_object_release( struct threadpool_object *object );
static struct threadpool *default_threadpool = NULL;
-static inline LONG interlocked_inc( PLONG dest )
-{
- return interlocked_xchg_add( dest, 1 ) + 1;
-}
-
-static inline LONG interlocked_dec( PLONG dest )
-{
- return interlocked_xchg_add( dest, -1 ) - 1;
-}
-
static void CALLBACK process_rtl_work_item( TP_CALLBACK_INSTANCE *instance, void *userdata )
{
struct rtl_work_item *item = userdata;
diff --git a/include/wine/port.h b/include/wine/port.h
index eb346e00fd3..e782ee00626 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -506,6 +506,16 @@ static inline __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int6
extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compare );
#endif
+static inline int interlocked_inc( int *dest )
+{
+ return interlocked_xchg_add( dest, 1 ) + 1;
+}
+
+static inline int interlocked_dec( int *dest )
+{
+ return interlocked_xchg_add( dest, -1 ) - 1;
+}
+
#else /* NO_LIBWINE_PORT */
#define __WINE_NOT_PORTABLE(func) func##_is_not_portable func##_is_not_portable
@@ -516,9 +526,11 @@ extern __int64 interlocked_cmpxchg64( __int64 *dest, __int64 xchg, __int64 compa
#define getopt_long_only __WINE_NOT_PORTABLE(getopt_long_only)
#define interlocked_cmpxchg __WINE_NOT_PORTABLE(interlocked_cmpxchg)
#define interlocked_cmpxchg_ptr __WINE_NOT_PORTABLE(interlocked_cmpxchg_ptr)
+#define interlocked_dec __WINE_NOT_PORTABLE(interlocked_dec)
+#define interlocked_inc __WINE_NOT_PORTABLE(interlocked_inc)
#define interlocked_xchg __WINE_NOT_PORTABLE(interlocked_xchg)
-#define interlocked_xchg_ptr __WINE_NOT_PORTABLE(interlocked_xchg_ptr)
#define interlocked_xchg_add __WINE_NOT_PORTABLE(interlocked_xchg_add)
+#define interlocked_xchg_ptr __WINE_NOT_PORTABLE(interlocked_xchg_ptr)
#define lstat __WINE_NOT_PORTABLE(lstat)
#define memcpy_unaligned __WINE_NOT_PORTABLE(memcpy_unaligned)
#undef memmove
--
2.13.1

View File

@ -0,0 +1,69 @@
From 52a0506018b5f61484935142b79e73dbbe0ae9d7 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:38:38 +0200
Subject: ntdll: Add inline versions of RtlEnterCriticalSection /
RtlLeaveCriticalSections.
---
dlls/ntdll/ntdll_misc.h | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 19d1e532759..c6c60090d10 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -27,6 +27,7 @@
#include "windef.h"
#include "winnt.h"
#include "winternl.h"
+#include "wine/debug.h"
#include "wine/server.h"
#define MAX_NT_PATH_LENGTH 277
@@ -198,6 +199,43 @@ extern int ntdll_wcstoumbs(DWORD flags, const WCHAR* src, int srclen, char* dst,
extern int CDECL NTDLL__vsnprintf( char *str, SIZE_T len, const char *format, __ms_va_list args ) DECLSPEC_HIDDEN;
extern int CDECL NTDLL__vsnwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, __ms_va_list args ) DECLSPEC_HIDDEN;
+#ifdef __WINE_WINE_PORT_H
+
+/* inline version of RtlEnterCriticalSection */
+static inline void enter_critical_section( RTL_CRITICAL_SECTION *crit )
+{
+ if (interlocked_inc( &crit->LockCount ))
+ {
+ if (crit->OwningThread == ULongToHandle(GetCurrentThreadId()))
+ {
+ crit->RecursionCount++;
+ return;
+ }
+ RtlpWaitForCriticalSection( crit );
+ }
+ crit->OwningThread = ULongToHandle(GetCurrentThreadId());
+ crit->RecursionCount = 1;
+}
+
+/* inline version of RtlLeaveCriticalSection */
+static inline void leave_critical_section( RTL_CRITICAL_SECTION *crit )
+{
+ WINE_DECLARE_DEBUG_CHANNEL(ntdll);
+ if (--crit->RecursionCount)
+ {
+ if (crit->RecursionCount > 0) interlocked_dec( &crit->LockCount );
+ else ERR_(ntdll)( "section %p is not acquired\n", crit );
+ }
+ else
+ {
+ crit->OwningThread = 0;
+ if (interlocked_dec( &crit->LockCount ) >= 0)
+ RtlpUnWaitCriticalSection( crit );
+ }
+}
+
+#endif /* __WINE_WINE_PORT_H */
+
/* load order */
enum loadorder
--
2.13.1

View File

@ -0,0 +1,228 @@
From 357104aee69fd26cf997692ba26a5e8bda1111de Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:39:23 +0200
Subject: ntdll: Use fast CS functions for heap locking.
---
dlls/ntdll/heap.c | 52 ++++++++++++++++++++++++++--------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index f4ddd7bd68a..f17356c740e 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -1527,7 +1527,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
flags |= heapPtr->flags;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if (!(flags & HEAP_NO_SERIALIZE))
- RtlEnterCriticalSection( &heapPtr->critSection );
+ enter_critical_section( &heapPtr->critSection );
if (block) /* only check this single memory block */
{
@@ -1550,7 +1550,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
ret = HEAP_ValidateInUseArena( subheap, arena, quiet );
if (!(flags & HEAP_NO_SERIALIZE))
- RtlLeaveCriticalSection( &heapPtr->critSection );
+ leave_critical_section( &heapPtr->critSection );
return ret;
}
@@ -1582,7 +1582,7 @@ static BOOL HEAP_IsRealArena( HEAP *heapPtr, /* [in] ptr to the heap */
LIST_FOR_EACH_ENTRY( large_arena, &heapPtr->large_list, ARENA_LARGE, entry )
if (!(ret = validate_large_arena( heapPtr, large_arena, quiet ))) break;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
return ret;
}
@@ -1756,9 +1756,9 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c
if (processHeap)
{
HEAP *heapPtr = subheap->heap;
- RtlEnterCriticalSection( &processHeap->critSection );
+ enter_critical_section( &processHeap->critSection );
list_add_head( &processHeap->entry, &heapPtr->entry );
- RtlLeaveCriticalSection( &processHeap->critSection );
+ leave_critical_section( &processHeap->critSection );
}
else if (!addr)
{
@@ -1796,9 +1796,9 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE heap )
if (heap == processHeap) return heap; /* cannot delete the main process heap */
/* remove it from the per-process list */
- RtlEnterCriticalSection( &processHeap->critSection );
+ enter_critical_section( &processHeap->critSection );
list_remove( &heapPtr->entry );
- RtlLeaveCriticalSection( &processHeap->critSection );
+ leave_critical_section( &processHeap->critSection );
heapPtr->critSection.DebugInfo->Spare[0] = 0;
RtlDeleteCriticalSection( &heapPtr->critSection );
@@ -1871,12 +1871,12 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
}
if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) enter_critical_section( &heapPtr->critSection );
if (rounded_size >= HEAP_MIN_LARGE_BLOCK_SIZE && (flags & HEAP_GROWABLE))
{
void *ret = allocate_large_block( heap, flags, size );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
if (!ret && (flags & HEAP_GENERATE_EXCEPTIONS)) RtlRaiseStatus( STATUS_NO_MEMORY );
TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, ret );
return ret;
@@ -1888,7 +1888,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
{
TRACE("(%p,%08x,%08lx): returning NULL\n",
heap, flags, size );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
return NULL;
}
@@ -1914,7 +1914,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size )
notify_alloc( pInUse + 1, size, flags & HEAP_ZERO_MEMORY );
initialize_block( pInUse + 1, size, pInUse->unused_bytes, flags );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
TRACE("(%p,%08x,%08lx): returning %p\n", heap, flags, size, pInUse + 1 );
return pInUse + 1;
@@ -1954,7 +1954,7 @@ BOOLEAN WINAPI RtlFreeHeap( HANDLE heap, ULONG flags, PVOID ptr )
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) enter_critical_section( &heapPtr->critSection );
/* Inform valgrind we are trying to free memory, so it can throw up an error message */
notify_free( ptr );
@@ -1968,12 +1968,12 @@ BOOLEAN WINAPI RtlFreeHeap( HANDLE heap, ULONG flags, PVOID ptr )
else
HEAP_MakeInUseBlockFree( subheap, pInUse );
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
TRACE("(%p,%08x,%p): returning TRUE\n", heap, flags, ptr );
return TRUE;
error:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p): returning FALSE\n", heap, flags, ptr );
return FALSE;
@@ -2015,7 +2015,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY |
HEAP_REALLOC_IN_PLACE_ONLY;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) enter_critical_section( &heapPtr->critSection );
rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags);
if (rounded_size < size) goto oom; /* overflow */
@@ -2109,19 +2109,19 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size
ret = pArena + 1;
done:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
TRACE("(%p,%08x,%p,%08lx): returning %p\n", heap, flags, ptr, size, ret );
return ret;
oom:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_NO_MEMORY );
TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heap, flags, ptr, size );
return NULL;
error:
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
RtlSetLastWin32ErrorAndNtStatusFromNtStatus( STATUS_INVALID_PARAMETER );
TRACE("(%p,%08x,%p,%08lx): returning NULL\n", heap, flags, ptr, size );
return NULL;
@@ -2167,7 +2167,7 @@ BOOLEAN WINAPI RtlLockHeap( HANDLE heap )
{
HEAP *heapPtr = HEAP_GetPtr( heap );
if (!heapPtr) return FALSE;
- RtlEnterCriticalSection( &heapPtr->critSection );
+ enter_critical_section( &heapPtr->critSection );
return TRUE;
}
@@ -2188,7 +2188,7 @@ BOOLEAN WINAPI RtlUnlockHeap( HANDLE heap )
{
HEAP *heapPtr = HEAP_GetPtr( heap );
if (!heapPtr) return FALSE;
- RtlLeaveCriticalSection( &heapPtr->critSection );
+ leave_critical_section( &heapPtr->critSection );
return TRUE;
}
@@ -2224,7 +2224,7 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
}
flags &= HEAP_NO_SERIALIZE;
flags |= heapPtr->flags;
- if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) enter_critical_section( &heapPtr->critSection );
pArena = (const ARENA_INUSE *)ptr - 1;
if (!validate_block_pointer( heapPtr, &subheap, pArena ))
@@ -2241,7 +2241,7 @@ SIZE_T WINAPI RtlSizeHeap( HANDLE heap, ULONG flags, const void *ptr )
{
ret = (pArena->size & ARENA_SIZE_MASK) - pArena->unused_bytes;
}
- if (!(flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
TRACE("(%p,%08x,%p): returning %08lx\n", heap, flags, ptr, ret );
return ret;
@@ -2288,7 +2288,7 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
if (!heapPtr || !entry) return STATUS_INVALID_PARAMETER;
- if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
+ if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) enter_critical_section( &heapPtr->critSection );
/* FIXME: enumerate large blocks too */
@@ -2393,7 +2393,7 @@ NTSTATUS WINAPI RtlWalkHeap( HANDLE heap, PVOID entry_ptr )
if (TRACE_ON(heap)) HEAP_DumpEntry(entry);
HW_end:
- if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) RtlLeaveCriticalSection( &heapPtr->critSection );
+ if (!(heapPtr->flags & HEAP_NO_SERIALIZE)) leave_critical_section( &heapPtr->critSection );
return ret;
}
@@ -2416,7 +2416,7 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
ULONG total = 1; /* main heap */
struct list *ptr;
- RtlEnterCriticalSection( &processHeap->critSection );
+ enter_critical_section( &processHeap->critSection );
LIST_FOR_EACH( ptr, &processHeap->entry ) total++;
if (total <= count)
{
@@ -2424,7 +2424,7 @@ ULONG WINAPI RtlGetProcessHeaps( ULONG count, HANDLE *heaps )
LIST_FOR_EACH( ptr, &processHeap->entry )
*heaps++ = LIST_ENTRY( ptr, HEAP, entry );
}
- RtlLeaveCriticalSection( &processHeap->critSection );
+ leave_critical_section( &processHeap->critSection );
return total;
}
--
2.13.1

View File

@ -0,0 +1,417 @@
From fac19f4dd587a1b8b23c87fe5ad11339d3cd3851 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:39:37 +0200
Subject: ntdll: Use fast CS functions for threadpool locking.
---
dlls/ntdll/threadpool.c | 96 ++++++++++++++++++++++++-------------------------
1 file changed, 48 insertions(+), 48 deletions(-)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index b723e6f66f8..f9dc6a5a441 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1191,7 +1191,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
TRACE( "starting timer queue thread\n" );
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
for (;;)
{
NtQuerySystemTime( &now );
@@ -1265,7 +1265,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
}
timerqueue.thread_running = FALSE;
- RtlLeaveCriticalSection( &timerqueue.cs );
+ leave_critical_section( &timerqueue.cs );
TRACE( "terminating timer queue thread\n" );
RtlExitUserThread( 0 );
@@ -1311,7 +1311,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timer->u.timer.period = 0;
timer->u.timer.window_length = 0;
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
/* Make sure that the timerqueue thread is running. */
if (!timerqueue.thread_running)
@@ -1332,7 +1332,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timerqueue.objcount++;
}
- RtlLeaveCriticalSection( &timerqueue.cs );
+ leave_critical_section( &timerqueue.cs );
return status;
}
@@ -1345,7 +1345,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
{
assert( timer->type == TP_OBJECT_TYPE_TIMER );
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
if (timer->u.timer.timer_initialized)
{
/* If timer was pending, remove it. */
@@ -1364,7 +1364,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
timer->u.timer.timer_initialized = FALSE;
}
- RtlLeaveCriticalSection( &timerqueue.cs );
+ leave_critical_section( &timerqueue.cs );
}
/***********************************************************************
@@ -1382,7 +1382,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
TRACE( "starting wait queue thread\n" );
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
for (;;)
{
@@ -1419,10 +1419,10 @@ static void CALLBACK waitqueue_thread_proc( void *param )
/* All wait objects have been destroyed, if no new wait objects are created
* within some amount of time, then we can shutdown this thread. */
assert( num_handles == 0 );
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
timeout.QuadPart = (ULONGLONG)THREADPOOL_WORKER_TIMEOUT * -10000;
status = NtWaitForMultipleObjects( 1, &bucket->update_event, TRUE, FALSE, &timeout );
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
if (status == STATUS_TIMEOUT && !bucket->objcount)
break;
@@ -1430,9 +1430,9 @@ static void CALLBACK waitqueue_thread_proc( void *param )
else
{
handles[num_handles] = bucket->update_event;
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
status = NtWaitForMultipleObjects( num_handles + 1, handles, TRUE, FALSE, &timeout );
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
if (status >= STATUS_WAIT_0 && status < STATUS_WAIT_0 + num_handles)
{
@@ -1505,7 +1505,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
if (!--waitqueue.num_buckets)
assert( list_empty( &waitqueue.buckets ) );
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
TRACE( "terminating wait queue thread\n" );
@@ -1534,7 +1534,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
wait->u.wait.timeout = 0;
wait->u.wait.handle = INVALID_HANDLE_VALUE;
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
/* Try to assign to existing bucket if possible. */
LIST_FOR_EACH_ENTRY( bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry )
@@ -1590,7 +1590,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
}
out:
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
return status;
}
@@ -1601,7 +1601,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
{
assert( wait->type == TP_OBJECT_TYPE_WAIT );
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
if (wait->u.wait.bucket)
{
struct waitqueue_bucket *bucket = wait->u.wait.bucket;
@@ -1613,7 +1613,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
NtSetEvent( bucket->update_event, NULL );
}
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
}
/***********************************************************************
@@ -1721,7 +1721,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool = default_threadpool;
}
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
/* Make sure that the threadpool has at least one thread. */
if (!pool->num_workers)
@@ -1735,7 +1735,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool->objcount++;
}
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
if (status != STATUS_SUCCESS)
return status;
@@ -1751,9 +1751,9 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
*/
static void tp_threadpool_unlock( struct threadpool *pool )
{
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
pool->objcount--;
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
tp_threadpool_release( pool );
}
@@ -1882,10 +1882,10 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
struct threadpool_group *group = object->group;
interlocked_inc( &group->refcount );
- RtlEnterCriticalSection( &group->cs );
+ enter_critical_section( &group->cs );
list_add_tail( &group->members, &object->group_entry );
object->is_group_member = TRUE;
- RtlLeaveCriticalSection( &group->cs );
+ leave_critical_section( &group->cs );
}
if (is_simple_callback)
@@ -1906,7 +1906,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
assert( !object->shutdown );
assert( !pool->shutdown );
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers &&
@@ -1929,7 +1929,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
RtlWakeConditionVariable( &pool->update_event );
}
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
}
/***********************************************************************
@@ -1942,7 +1942,7 @@ static void tp_object_cancel( struct threadpool_object *object )
struct threadpool *pool = object->pool;
LONG pending_callbacks = 0;
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
if (object->num_pending_callbacks)
{
pending_callbacks = object->num_pending_callbacks;
@@ -1952,7 +1952,7 @@ static void tp_object_cancel( struct threadpool_object *object )
if (object->type == TP_OBJECT_TYPE_WAIT)
object->u.wait.signaled = 0;
}
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
while (pending_callbacks--)
tp_object_release( object );
@@ -1968,7 +1968,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
{
struct threadpool *pool = object->pool;
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
if (group_wait)
{
while (object->num_pending_callbacks || object->num_running_callbacks)
@@ -1979,7 +1979,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
while (object->num_pending_callbacks || object->num_associated_callbacks)
RtlSleepConditionVariableCS( &object->finished_event, &pool->cs, NULL );
}
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
}
/***********************************************************************
@@ -2017,13 +2017,13 @@ static BOOL tp_object_release( struct threadpool_object *object )
{
struct threadpool_group *group = object->group;
- RtlEnterCriticalSection( &group->cs );
+ enter_critical_section( &group->cs );
if (object->is_group_member)
{
list_remove( &object->group_entry );
object->is_group_member = FALSE;
}
- RtlLeaveCriticalSection( &group->cs );
+ leave_critical_section( &group->cs );
tp_group_release( group );
}
@@ -2052,7 +2052,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "starting worker thread for pool %p\n", pool );
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
pool->num_busy_workers--;
for (;;)
{
@@ -2078,7 +2078,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
object->num_associated_callbacks++;
object->num_running_callbacks++;
pool->num_busy_workers++;
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
/* Initialize threadpool instance struct. */
callback_instance = (TP_CALLBACK_INSTANCE *)&instance;
@@ -2171,7 +2171,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
}
skip_cleanup:
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
pool->num_busy_workers--;
/* Simple callbacks are automatically shutdown after execution. */
@@ -2213,7 +2213,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
}
}
pool->num_workers--;
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
TRACE( "terminating worker thread for pool %p\n", pool );
tp_threadpool_release( pool );
@@ -2389,7 +2389,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
return STATUS_SUCCESS;
pool = object->pool;
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers)
@@ -2404,7 +2404,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
}
}
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
this->may_run_long = TRUE;
return status;
}
@@ -2485,13 +2485,13 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
return;
pool = object->pool;
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
object->num_associated_callbacks--;
if (!object->num_pending_callbacks && !object->num_associated_callbacks)
RtlWakeAllConditionVariable( &object->finished_event );
- RtlLeaveCriticalSection( &pool->cs );
+ leave_critical_section( &pool->cs );
this->associated = FALSE;
}
@@ -2543,7 +2543,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
TRACE( "%p %u %p\n", group, cancel_pending, userdata );
- RtlEnterCriticalSection( &this->cs );
+ enter_critical_section( &this->cs );
/* Unset group, increase references, and mark objects for shutdown */
LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry )
@@ -2569,7 +2569,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
list_init( &members );
list_move_tail( &members, &this->members );
- RtlLeaveCriticalSection( &this->cs );
+ leave_critical_section( &this->cs );
/* Cancel pending callbacks if requested */
if (cancel_pending)
@@ -2669,10 +2669,10 @@ VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
TRACE( "%p %u\n", pool, maximum );
- RtlEnterCriticalSection( &this->cs );
+ enter_critical_section( &this->cs );
this->max_workers = max( maximum, 1 );
this->min_workers = min( this->min_workers, this->max_workers );
- RtlLeaveCriticalSection( &this->cs );
+ leave_critical_section( &this->cs );
}
/***********************************************************************
@@ -2685,7 +2685,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
TRACE( "%p %u\n", pool, minimum );
- RtlEnterCriticalSection( &this->cs );
+ enter_critical_section( &this->cs );
while (this->num_workers < minimum)
{
@@ -2700,7 +2700,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
this->max_workers = max( this->min_workers, this->max_workers );
}
- RtlLeaveCriticalSection( &this->cs );
+ leave_critical_section( &this->cs );
return !status;
}
@@ -2716,7 +2716,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
TRACE( "%p %p %u %u\n", timer, timeout, period, window_length );
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
assert( this->u.timer.timer_initialized );
this->u.timer.timer_set = timeout != NULL;
@@ -2776,7 +2776,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
this->u.timer.timer_pending = TRUE;
}
- RtlLeaveCriticalSection( &timerqueue.cs );
+ leave_critical_section( &timerqueue.cs );
if (submit_timer)
tp_object_submit( this, FALSE );
@@ -2793,7 +2793,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
TRACE( "%p %p %p\n", wait, handle, timeout );
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
assert( this->u.wait.bucket );
this->u.wait.handle = handle;
@@ -2837,7 +2837,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
NtSetEvent( bucket->update_event, NULL );
}
- RtlLeaveCriticalSection( &waitqueue.cs );
+ leave_critical_section( &waitqueue.cs );
if (submit_wait)
tp_object_submit( this, FALSE );
--
2.13.1

View File

@ -234,6 +234,7 @@ patch_enable_all ()
enable_ntdll_Attach_Process_DLLs="$1"
enable_ntdll_Builtin_Prot="$1"
enable_ntdll_CLI_Images="$1"
enable_ntdll_CriticalSection="$1"
enable_ntdll_DOS_Attributes="$1"
enable_ntdll_Dealloc_Thread_Stack="$1"
enable_ntdll_DeviceType_Systemroot="$1"
@ -971,6 +972,9 @@ patch_enable ()
ntdll-CLI_Images)
enable_ntdll_CLI_Images="$2"
;;
ntdll-CriticalSection)
enable_ntdll_CriticalSection="$2"
;;
ntdll-DOS_Attributes)
enable_ntdll_DOS_Attributes="$2"
;;
@ -5963,6 +5967,24 @@ if test "$enable_ntdll_CLI_Images" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-CriticalSection
# |
# | Modified files:
# | * dlls/ntdll/critsection.c, dlls/ntdll/heap.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/threadpool.c, include/wine/port.h
# |
if test "$enable_ntdll_CriticalSection" -eq 1; then
patch_apply ntdll-CriticalSection/0001-include-Move-interlocked_inc-dec-to-port.h.patch
patch_apply ntdll-CriticalSection/0002-ntdll-Add-inline-versions-of-RtlEnterCriticalSection.patch
patch_apply ntdll-CriticalSection/0003-ntdll-Use-fast-CS-functions-for-heap-locking.patch
patch_apply ntdll-CriticalSection/0004-ntdll-Use-fast-CS-functions-for-threadpool-locking.patch
(
printf '%s\n' '+ { "Sebastian Lackner", "include: Move interlocked_inc/dec to port.h.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Add inline versions of RtlEnterCriticalSection / RtlLeaveCriticalSections.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Use fast CS functions for heap locking.", 1 },';
printf '%s\n' '+ { "Sebastian Lackner", "ntdll: Use fast CS functions for threadpool locking.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-DOS_Attributes
# |
# | This patchset fixes the following Wine bugs: