diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 1a18899d6c3..6fb14bbcbf4 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -712,6 +712,7 @@ @ stdcall InitAtomTable(long) @ stdcall InitializeCriticalSection(ptr) @ stdcall InitializeCriticalSectionAndSpinCount(ptr long) +@ stdcall InitializeCriticalSectionEx(ptr long long) @ stdcall InitializeSListHead(ptr) ntdll.RtlInitializeSListHead @ stdcall InterlockedCompareExchange (ptr long long) @ stdcall InterlockedDecrement(ptr) diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c index 0032d17ef92..da558fd63d3 100644 --- a/dlls/kernel32/sync.c +++ b/dlls/kernel32/sync.c @@ -350,8 +350,7 @@ DWORD WINAPI SignalObjectAndWait( HANDLE hObjectToSignal, HANDLE hObjectToWaitOn */ void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit ) { - NTSTATUS ret = RtlInitializeCriticalSection( crit ); - if (ret) RtlRaiseStatus( ret ); + InitializeCriticalSectionEx( crit, 0, 0 ); } /*********************************************************************** @@ -372,7 +371,29 @@ void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit ) */ BOOL WINAPI InitializeCriticalSectionAndSpinCount( CRITICAL_SECTION *crit, DWORD spincount ) { - NTSTATUS ret = RtlInitializeCriticalSectionAndSpinCount( crit, spincount ); + return InitializeCriticalSectionEx( crit, spincount, 0 ); +} + +/*********************************************************************** + * InitializeCriticalSectionEx (KERNEL32.@) + * + * Initialise a critical section with a spin count and flags. + * + * PARAMS + * crit [O] Critical section to initialise. + * spincount [I] Number of times to spin upon contention. + * flags [I] CRITICAL_SECTION_ flags from winbase.h. + * + * RETURNS + * Success: TRUE. + * Failure: Nothing. If the function fails an exception is raised. + * + * NOTES + * spincount is ignored on uni-processor systems. + */ +BOOL WINAPI InitializeCriticalSectionEx( CRITICAL_SECTION *crit, DWORD spincount, DWORD flags ) +{ + NTSTATUS ret = RtlInitializeCriticalSectionEx( crit, spincount, flags ); if (ret) RtlRaiseStatus( ret ); return !ret; } diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c index 0fa47c49bce..284634353b4 100644 --- a/dlls/ntdll/critsection.c +++ b/dlls/ntdll/critsection.c @@ -247,13 +247,14 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout ) * STATUS_SUCCESS. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSectionAndSpinCount(), RtlDeleteCriticalSection(), * RtlEnterCriticalSection(), RtlLeaveCriticalSection(), * RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount() */ NTSTATUS WINAPI RtlInitializeCriticalSection( RTL_CRITICAL_SECTION *crit ) { - return RtlInitializeCriticalSectionAndSpinCount( crit, 0 ); + return RtlInitializeCriticalSectionEx( crit, 0, 0 ); } /*********************************************************************** @@ -272,13 +273,53 @@ NTSTATUS WINAPI RtlInitializeCriticalSection( RTL_CRITICAL_SECTION *crit ) * Available on NT4 SP3 or later. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlDeleteCriticalSection(), * RtlEnterCriticalSection(), RtlLeaveCriticalSection(), * RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount() */ NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION *crit, ULONG spincount ) { - crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG)); + return RtlInitializeCriticalSectionEx( crit, spincount, 0 ); +} + +/*********************************************************************** + * RtlInitializeCriticalSectionEx (NTDLL.@) + * + * Initialises a new critical section with a given spin count and flags. + * + * PARAMS + * crit [O] Critical section to initialise. + * spincount [I] Number of times to spin upon contention. + * flags [I] RTL_CRITICAL_SECTION_FLAG_ flags from winnt.h. + * + * RETURNS + * STATUS_SUCCESS. + * + * NOTES + * Available on Vista or later. + * + * SEE + * RtlInitializeCriticalSection(), RtlDeleteCriticalSection(), + * RtlEnterCriticalSection(), RtlLeaveCriticalSection(), + * RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount() + */ +NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULONG spincount, ULONG flags ) +{ + if (flags & (RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN|RTL_CRITICAL_SECTION_FLAG_STATIC_INIT)) + FIXME("(%p,%u,0x%08x) semi-stub\n", crit, spincount, flags); + + /* FIXME: if RTL_CRITICAL_SECTION_FLAG_STATIC_INIT is given, we should use + * memory from a static pool to hold the debug info. Then heap.c could pass + * this flag rather than initialising the process heap CS by hand. If this + * is done, then debug info should be managed through Rtlp[Allocate|Free]DebugInfo + * so (e.g.) MakeCriticalSectionGlobal() doesn't free it using HeapFree(). + */ + if (flags & RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO) + crit->DebugInfo = NULL; + else + crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG)); + if (crit->DebugInfo) { crit->DebugInfo->Type = 0; @@ -315,6 +356,7 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount( RTL_CRITICAL_SECTION * * If the system is not SMP, spincount is ignored and set to 0. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() @@ -339,6 +381,7 @@ ULONG WINAPI RtlSetCriticalSectionSpinCount( RTL_CRITICAL_SECTION *crit, ULONG s * STATUS_SUCCESS. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() @@ -380,6 +423,7 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) * faster. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() @@ -442,6 +486,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) * faster. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() @@ -473,6 +518,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) * STATUS_SUCCESS. The critical section is held by the caller. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlSetCriticalSectionSpinCount(), * RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() @@ -526,6 +572,7 @@ done: * Failure: FALSE. The critical section is currently held by another thread. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlLeaveCriticalSection(), RtlSetCriticalSectionSpinCount() @@ -561,6 +608,7 @@ BOOL WINAPI RtlTryEnterCriticalSection( RTL_CRITICAL_SECTION *crit ) * STATUS_SUCCESS. * * SEE + * RtlInitializeCriticalSectionEx(), * RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * RtlDeleteCriticalSection(), RtlEnterCriticalSection(), * RtlSetCriticalSectionSpinCount(), RtlTryEnterCriticalSection() diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index ed89cbd4b36..575f99da373 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -664,6 +664,7 @@ @ stub RtlInitializeContext @ stdcall RtlInitializeCriticalSection(ptr) @ stdcall RtlInitializeCriticalSectionAndSpinCount(ptr long) +@ stdcall RtlInitializeCriticalSectionEx(ptr long long) @ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr) # @ stub RtlInitializeGenericTableAvl @ stdcall RtlInitializeHandleTable(long long ptr) diff --git a/include/winbase.h b/include/winbase.h index 433b98510d6..c47a1a500fe 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -54,6 +54,8 @@ typedef RTL_CRITICAL_SECTION_DEBUG CRITICAL_SECTION_DEBUG; typedef PRTL_CRITICAL_SECTION_DEBUG PCRITICAL_SECTION_DEBUG; typedef PRTL_CRITICAL_SECTION_DEBUG LPCRITICAL_SECTION_DEBUG; +#define CRITICAL_SECTION_NO_DEBUG_INFO RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO + typedef WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACK; #define EXCEPTION_DEBUG_EVENT 1 @@ -1777,6 +1779,7 @@ WINBASEAPI BOOL WINAPI InitAtomTable(DWORD); WINADVAPI BOOL WINAPI InitializeAcl(PACL,DWORD,DWORD); WINBASEAPI void WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit); WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *,DWORD); +WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(CRITICAL_SECTION *,DWORD,DWORD); WINADVAPI BOOL WINAPI InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD); WINADVAPI BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); WINBASEAPI VOID WINAPI InitializeSListHead(PSLIST_HEADER); diff --git a/include/winnt.h b/include/winnt.h index 70853638855..f9ae9d4a4a5 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -4700,6 +4700,12 @@ typedef struct _RTL_CRITICAL_SECTION { ULONG_PTR SpinCount; } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; +#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO 0x1000000 +#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 0x2000000 +#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT 0x4000000 +#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS 0xFF000000 +#define RTL_CRITICAL_SECTION_FLAG_RESERVED (RTL_CRITICAL_SECTION_ALL_FLAG_BITS & ~0x7000000) + typedef VOID (NTAPI * WAITORTIMERCALLBACKFUNC) (PVOID, BOOLEAN ); typedef VOID (NTAPI * PFLS_CALLBACK_FUNCTION) ( PVOID ); diff --git a/include/winternl.h b/include/winternl.h index 39339c2b77a..fe2f83d3feb 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2219,7 +2219,8 @@ NTSYSAPI NTSTATUS WINAPI RtlInitAnsiStringEx(PANSI_STRING,PCSZ); NTSYSAPI void WINAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR); NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING,PCWSTR); NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSection(RTL_CRITICAL_SECTION *); -NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount(RTL_CRITICAL_SECTION *,DWORD); +NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionAndSpinCount(RTL_CRITICAL_SECTION *,ULONG); +NTSYSAPI NTSTATUS WINAPI RtlInitializeCriticalSectionEx(RTL_CRITICAL_SECTION *,ULONG,ULONG); NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP,PULONG,ULONG); NTSYSAPI void WINAPI RtlInitializeHandleTable(ULONG,ULONG,RTL_HANDLE_TABLE *); NTSYSAPI void WINAPI RtlInitializeResource(LPRTL_RWLOCK);