CVS: winex/dlls/ntdll critsection.c,1.17,1.18
[email protected] 31 Jul 2007 18:00:48 -0000
| Newsgroups | gmane.comp.emulators.winex.cvs |
|---|---|
| Message-ID | <[email protected]> |
Subject: winex/dlls/ntdll critsection.c,1.17,1.18Update of /var/lib/cvsd/cvsroot/winex/dlls/ntdll
In directory agravaine:/tmp/cvs-serv24840/dlls/ntdll
Modified Files:
critsection.c
Log Message:
- add assembly versions of RtlEnterCriticalSection and RtlLeaveCriticalSection to optimize the fast path (ie, that the CS is available for us to take)
Index: critsection.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/ntdll/critsection.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- critsection.c 30 Mar 2007 15:55:17 -0000 1.17
+++ critsection.c 31 Jul 2007 18:00:46 -0000 1.18
@@ -14,6 +14,7 @@
#endif
#include "winerror.h"
#include "winternl.h"
+#include "wine/port.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
@@ -523,37 +524,74 @@
/***********************************************************************
+ * function called by EnterCriticalSection if the section is contested
+ * Note - must be WINAPI (and non-static?) to ensure stack alignment
+ * fixups are done on MacOS X, since we don't do them in the
+ * hand-coded EnterCriticalSection()
+*/
+NTSTATUS WINAPI EnterContestedCriticalSection (RTL_CRITICAL_SECTION *crit,
+ DWORD dwThreadId)
+{
+ DWORD dwCount;
+
+ if (crit->OwningThread == dwThreadId)
+ {
+ crit->RecursionCount++;
+ return STATUS_SUCCESS;
+ }
+
+ /* Spin if desired */
+ for (dwCount = crit->SpinCount; dwCount; dwCount--)
+ {
+ if (RtlTryEnterCriticalSection (crit))
+ return STATUS_SUCCESS;
+ }
+
+ /* Blocking wait for it */
+ RtlpWaitForCriticalSection (crit);
+
+ crit->OwningThread = dwThreadId;
+ crit->RecursionCount = 1;
+
+ return STATUS_SUCCESS;
+}
+
+
+/***********************************************************************
* RtlEnterCriticalSection (NTDLL.@)
+ *
*/
+#ifdef __i386__
+__ASM_GLOBAL_FUNC(RtlEnterCriticalSection,
+ "mov %fs:0x24,%ecx\n\t"
+ "mov 0x4(%esp),%edx\n\t"
+ "lock; incl 0x4(%edx)\n\t"
+ "jne 1f\n\t"
+ "mov %ecx,%eax\n\t"
+ "movl $0x1,0x8(%edx)\n\t"
+ "mov %eax,0xc(%edx)\n\t"
+ "xor %eax,%eax\n\t"
+ "ret $0x4\n\t"
+ "1: push %ecx\n\t"
+ "push %edx\n\t"
+ "call " __ASM_NAME("EnterContestedCriticalSection") "\n\t"
+ "ret $0x4");
+#else
NTSTATUS WINAPI RtlEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
{
- const DWORD dwThreadId = GetCurrentThreadId();
-
- if (interlocked_inc( &crit->LockCount ))
- {
- DWORD dwCount;
+ const DWORD dwThreadId = GetCurrentThreadId ();
- if (crit->OwningThread == dwThreadId)
- {
- crit->RecursionCount++;
- return STATUS_SUCCESS;
- }
-
- /* Spin if desired */
- for( dwCount = crit->SpinCount; dwCount; dwCount-- )
- {
- if( RtlTryEnterCriticalSection( crit ) ) return STATUS_SUCCESS;
- }
+ if (!interlocked_inc (&crit->LockCount))
+ {
+ crit->OwningThread = dwThreadId;
+ crit->RecursionCount = 1;
- /* Blocking wait for it */
- RtlpWaitForCriticalSection( crit );
- }
-
- crit->OwningThread = dwThreadId;
- crit->RecursionCount = 1;
+ return STATUS_SUCCESS;
+ }
- return STATUS_SUCCESS;
+ return EnterContestedCriticalSection (crit, dwThreadId);
}
+#endif
/***********************************************************************
@@ -581,6 +619,23 @@
/***********************************************************************
* RtlLeaveCriticalSection (NTDLL.@)
*/
+#ifdef __i386__
+__ASM_GLOBAL_FUNC(RtlLeaveCriticalSection,
+ "mov 0x4(%esp),%edx\n\t"
+ "xor %eax,%eax\n\t"
+ "decl 0x8(%edx)\n\t"
+ "jne 1f\n\t"
+ "mov %eax,0xc(%edx)\n\t"
+ "lock; decl 0x4(%edx)\n\t"
+ "jge 2f\n\t"
+ "ret $0x4\n\t"
+ "1: lock; decl 0x4(%edx)\n\t"
+ "ret $0x4\n\t"
+ "2: push %edx\n\t"
+ "call " __ASM_NAME("RtlpUnWaitCriticalSection") "\n\t"
+ "xor %eax,%eax\n\t"
+ "ret $0x4");
+#else
NTSTATUS WINAPI RtlLeaveCriticalSection( RTL_CRITICAL_SECTION *crit )
{
if (--crit->RecursionCount) interlocked_dec( &crit->LockCount );
@@ -595,3 +650,4 @@
}
return STATUS_SUCCESS;
}
+#endif