Optimize Critical Section Functions
Robert Shearman
rob at codeweavers.com
Fri Aug 20 10:50:36 CDT 2004
Hi,
With this patch GCC generates better code for critical sections in the
case of the fast paths with no contention.
Rob
Changelog:
Optimize critical section functions by telling GCC how likely certain
branches are.
-------------- next part --------------
Index: wine/dlls/ntdll/critsection.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/critsection.c,v
retrieving revision 1.26
diff -u -p -r1.26 critsection.c
--- wine/dlls/ntdll/critsection.c 17 Jun 2004 23:11:08 -0000 1.26
+++ wine/dlls/ntdll/critsection.c 20 Aug 2004 15:46:18 -0000
@@ -36,6 +36,14 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
WINE_DECLARE_DEBUG_CHANNEL(relay);
+#ifdef __GNUC__
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define likely(x) !!(x)
+# define unlikely(x) !!(x)
+#endif
+
inline static LONG interlocked_inc( PLONG dest )
{
return interlocked_xchg_add( dest, 1 ) + 1;
@@ -61,7 +69,7 @@ inline static void small_pause(void)
static inline HANDLE get_semaphore( RTL_CRITICAL_SECTION *crit )
{
HANDLE ret = crit->LockSemaphore;
- if (!ret)
+ if (unlikely( !ret ))
{
HANDLE sem;
if (NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 )) return 0;
@@ -209,7 +217,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSecti
time.QuadPart = -5000 * 10000; /* 5 seconds */
status = NtWaitForSingleObject( sem, FALSE, &time );
- if ( status == WAIT_TIMEOUT )
+ if (unlikely( status == WAIT_TIMEOUT ))
{
const char *name = NULL;
if (crit->DebugInfo) name = (char *)crit->DebugInfo->Spare[1];
@@ -226,7 +234,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSecti
status = NtWaitForSingleObject( sem, FALSE, &time );
}
}
- if (status == STATUS_WAIT_0) return STATUS_SUCCESS;
+ if (likely( status == STATUS_WAIT_0 )) return STATUS_SUCCESS;
/* Throw exception only for Wine internal locks */
if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[1])) continue;
@@ -270,7 +278,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSectio
*/
NTSTATUS WINAPI RtlEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
{
- if (crit->SpinCount)
+ if (unlikely( crit->SpinCount ))
{
ULONG count;
@@ -286,7 +294,7 @@ NTSTATUS WINAPI RtlEnterCriticalSection(
}
}
- if (interlocked_inc( &crit->LockCount ))
+ if (unlikely( interlocked_inc( &crit->LockCount ) ))
{
if (crit->OwningThread == (HANDLE)GetCurrentThreadId())
{
@@ -348,11 +356,11 @@ BOOL WINAPI RtlTryEnterCriticalSection(
*/
NTSTATUS WINAPI RtlLeaveCriticalSection( RTL_CRITICAL_SECTION *crit )
{
- if (--crit->RecursionCount) interlocked_dec( &crit->LockCount );
+ if (likely( --crit->RecursionCount )) interlocked_dec( &crit->LockCount );
else
{
crit->OwningThread = 0;
- if (interlocked_dec( &crit->LockCount ) >= 0)
+ if (unlikely( interlocked_dec( &crit->LockCount ) >= 0 ))
{
/* someone is waiting */
RtlpUnWaitCriticalSection( crit );
More information about the wine-patches
mailing list