Author: tkreuzer
Date: Mon Jan 14 13:55:12 2013
New Revision: 58175
URL:
http://svn.reactos.org/svn/reactos?rev=58175&view=rev
Log:
[NTOSKRNL] Initialize MmCriticalSectionTimeout and use it to setup the value in the PEB
(We currently continue to use 2.5 minutes, as opposed to the 30 days that Windows uses).
Probe and copy the timeout value in NtWaitForKeyedEvent and NtReleaseKeyedEvent.
[RTL] Use RtlpTimeout for critical sections, which is initialized from the PEB. Implement
using the LowMemory keyed event, when allocating the normal event failed.
Modified:
trunk/reactos/dll/ntdll/ldr/ldrinit.c
trunk/reactos/lib/rtl/critical.c
trunk/reactos/ntoskrnl/ex/keyedevt.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
Modified: trunk/reactos/dll/ntdll/ldr/ldrinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/ldrinit.c?re…
==============================================================================
--- trunk/reactos/dll/ntdll/ldr/ldrinit.c [iso-8859-1] (original)
+++ trunk/reactos/dll/ntdll/ldr/ldrinit.c [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -48,7 +48,7 @@
ULONG LdrpNumberOfTlsEntries;
ULONG LdrpNumberOfProcessors;
PVOID NtDllBase;
-LARGE_INTEGER RtlpTimeout;
+extern LARGE_INTEGER RtlpTimeout;
BOOLEAN RtlpTimeoutDisable;
LIST_ENTRY LdrpHashTable[LDR_HASH_TABLE_ENTRIES];
LIST_ENTRY LdrpDllNotificationList;
Modified: trunk/reactos/lib/rtl/critical.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/critical.c?rev=581…
==============================================================================
--- trunk/reactos/lib/rtl/critical.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/critical.c [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -21,6 +21,7 @@
static BOOLEAN RtlpCritSectInitialized = FALSE;
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS];
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS];
+LARGE_INTEGER RtlpTimeout;
/* FUNCTIONS *****************************************************************/
@@ -39,6 +40,7 @@
* None
*
*--*/
+_At_(CriticalSection->LockSemaphore, _Post_notnull_)
VOID
NTAPI
RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
@@ -47,31 +49,38 @@
HANDLE hNewEvent;
NTSTATUS Status;
- /* Chevk if we have an event */
- if (!hEvent) {
+ /* Check if we have an event */
+ if (!hEvent)
+ {
/* No, so create it */
- if (!NT_SUCCESS(Status = NtCreateEvent(&hNewEvent,
- EVENT_ALL_ACCESS,
- NULL,
- SynchronizationEvent,
- FALSE))) {
-
- /* We failed, this is bad... */
+ Status = NtCreateEvent(&hNewEvent,
+ EVENT_ALL_ACCESS,
+ NULL,
+ SynchronizationEvent,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
DPRINT1("Failed to Create Event!\n");
- InterlockedDecrement(&CriticalSection->LockCount);
- RtlRaiseStatus(Status);
- return;
+
+ /* Use INVALID_HANDLE_VALUE (-1) to signal that the global
+ keyed event must be used */
+ hNewEvent = INVALID_HANDLE_VALUE;
}
+
DPRINT("Created Event: %p \n", hNewEvent);
+ /* Exchange the LockSemaphore field with the new handle, if it is still 0 */
if
(InterlockedCompareExchangePointer((PVOID*)&CriticalSection->LockSemaphore,
(PVOID)hNewEvent,
- 0)) {
-
- /* Some just created an event */
- DPRINT("Closing already created event: %p\n", hNewEvent);
- NtClose(hNewEvent);
+ NULL) != NULL)
+ {
+ /* Someone else just created an event */
+ if (hEvent != INVALID_HANDLE_VALUE)
+ {
+ DPRINT("Closing already created event: %p\n", hNewEvent);
+ NtClose(hNewEvent);
+ }
}
}
@@ -100,13 +109,6 @@
NTSTATUS Status;
EXCEPTION_RECORD ExceptionRecord;
BOOLEAN LastChance = FALSE;
- LARGE_INTEGER Timeout;
-
- /* Wait 2.5 minutes */
- Timeout.QuadPart = 150000L * (ULONGLONG)10000;
- Timeout.QuadPart = -Timeout.QuadPart;
- /* ^^ HACK HACK HACK. Good way:
- Timeout = &NtCurrentPeb()->CriticalSectionTimeout */
/* Do we have an Event yet? */
if (!CriticalSection->LockSemaphore) {
@@ -127,10 +129,22 @@
if (CriticalSection->DebugInfo)
CriticalSection->DebugInfo->ContentionCount++;
- /* Wait on the Event */
- Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
- FALSE,
- &Timeout);
+ /* Check if allocating the event failed */
+ if (CriticalSection->LockSemaphore == INVALID_HANDLE_VALUE)
+ {
+ /* Use the global keyed event (NULL as keyed event handle) */
+ Status = NtWaitForKeyedEvent(NULL,
+ CriticalSection,
+ FALSE,
+ &RtlpTimeout);
+ }
+ else
+ {
+ /* Wait on the Event */
+ Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
+ FALSE,
+ &RtlpTimeout);
+ }
/* We have Timed out */
if (Status == STATUS_TIMEOUT) {
@@ -192,7 +206,18 @@
DPRINT("Signaling Critical Section Event: %p, %p\n",
CriticalSection,
CriticalSection->LockSemaphore);
- Status = NtSetEvent(CriticalSection->LockSemaphore, NULL);
+
+ /* Check if this critical section needs to use the keyed event */
+ if (CriticalSection->LockSemaphore == INVALID_HANDLE_VALUE)
+ {
+ /* Release keyed event */
+ Status = NtReleaseKeyedEvent(NULL, CriticalSection, FALSE, &RtlpTimeout);
+ }
+ else
+ {
+ /* Set the event */
+ Status = NtSetEvent(CriticalSection->LockSemaphore, NULL);
+ }
if (!NT_SUCCESS(Status)) {
Modified: trunk/reactos/ntoskrnl/ex/keyedevt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/keyedevt.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/keyedevt.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/keyedevt.c [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -239,7 +239,7 @@
TRUE);
}
-_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
NtCreateKeyedEvent(
@@ -316,7 +316,7 @@
return Status;
}
-_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
NtOpenKeyedEvent(
@@ -365,18 +365,35 @@
return Status;
}
-_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
NtWaitForKeyedEvent(
- _In_ HANDLE Handle,
+ _In_opt_ HANDLE Handle,
_In_ PVOID Key,
_In_ BOOLEAN Alertable,
- _In_ PLARGE_INTEGER Timeout)
+ _In_opt_ PLARGE_INTEGER Timeout)
{
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PEX_KEYED_EVENT KeyedEvent;
NTSTATUS Status;
+ LARGE_INTEGER TimeoutCopy;
+
+ /* Check if the caller passed a timeout value and this is from user mode */
+ if ((Timeout != NULL) && (PreviousMode != KernelMode))
+ {
+ _SEH2_TRY
+ {
+ ProbeForRead(Timeout, sizeof(*Timeout), 1);
+ TimeoutCopy = *Timeout;
+ Timeout = &TimeoutCopy;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
/* Check if the caller provided a handle */
if (Handle != NULL)
@@ -408,18 +425,35 @@
return Status;
}
-_IRQL_requires_max_(APC_LEVEL)
+_IRQL_requires_max_(PASSIVE_LEVEL)
NTSTATUS
NTAPI
NtReleaseKeyedEvent(
- _In_ HANDLE Handle,
+ _In_opt_ HANDLE Handle,
_In_ PVOID Key,
_In_ BOOLEAN Alertable,
- _In_ PLARGE_INTEGER Timeout)
+ _In_opt_ PLARGE_INTEGER Timeout)
{
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
PEX_KEYED_EVENT KeyedEvent;
NTSTATUS Status;
+ LARGE_INTEGER TimeoutCopy;
+
+ /* Check if the caller passed a timeout value and this is from user mode */
+ if ((Timeout != NULL) && (PreviousMode != KernelMode))
+ {
+ _SEH2_TRY
+ {
+ ProbeForRead(Timeout, sizeof(*Timeout), 1);
+ TimeoutCopy = *Timeout;
+ Timeout = &TimeoutCopy;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+ }
/* Check if the caller provided a handle */
if (Handle != NULL)
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -713,6 +713,7 @@
extern PVOID MmHighSectionBase;
extern SIZE_T MmSystemLockPagesCount;
extern ULONG_PTR MmSubsectionBase;
+extern LARGE_INTEGER MmCriticalSectionTimeout;
BOOLEAN
FORCEINLINE
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -373,6 +373,9 @@
/* Number of free pages in the loader block */
PFN_NUMBER MiNumberOfFreePages = 0;
+/* Timeout value for critical sections (2.5 minutes) */
+ULONG MmCritsectTimeoutSeconds = 150; // NT value: 720 * 60 * 60; (30 days)
+LARGE_INTEGER MmCriticalSectionTimeout;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -2119,6 +2122,9 @@
/* Initialize the user mode image list */
InitializeListHead(&MmLoadedUserImageList);
+ /* Initialize critical section timeout value (relative time is negative) */
+ MmCriticalSectionTimeout.QuadPart = MmCritsectTimeoutSeconds * (-10000000LL);
+
/* Initialize the paged pool mutex and the section commit mutex */
KeInitializeGuardedMutex(&MmPagedPoolMutex);
KeInitializeGuardedMutex(&MmSectionCommitMutex);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Mon Jan 14 13:55:12 2013
@@ -690,9 +690,9 @@
/*Peb->HeapSegmentReserve = MmHeapSegmentReserve;
Peb->HeapSegmentCommit = MmHeapSegmentCommit;
Peb->HeapDeCommitTotalFreeThreshold = MmHeapDeCommitTotalFreeThreshold;
- Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;
- Peb->CriticalSectionTimeout = MmCriticalSectionTimeout;
- Peb->MinimumStackCommit = MmMinimumStackCommitInBytes;
+ Peb->HeapDeCommitFreeBlockThreshold = MmHeapDeCommitFreeBlockThreshold;*/
+ Peb->CriticalSectionTimeout = MmCriticalSectionTimeout;
+ /*Peb->MinimumStackCommit = MmMinimumStackCommitInBytes;
*/
Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
Peb->ProcessHeaps = (PVOID*)(Peb + 1);