Author: ion
Date: Wed May 9 01:35:10 2007
New Revision: 26654
URL:
http://svn.reactos.org/svn/reactos?rev=26654&view=rev
Log:
- Fix broken definition of IsBoostAllowed which would cause ERESOURCE boosts to be applied
backwards.
- Use cleaner, inlined definitions for ExAcquire/ReleaseResourceLock.
- Convert ERESOURCE code to use a Queued In-Stack Spinlock instead of a regular spinlock.
- Force usage of the spinlock instead of cli/sti for DBG builds, and enable strict sanity
checks.
- Fix incorrect check in ExpCheckForApcsDisabled.
- Properly handle memory starvation in the contended path.
- Make sure to allocate a semaphore if needed during ExAcquireSharedStarveExclusive.
- Fix multiple bugs in ExIsResourceAcquiredSharedLite.
- ExReleaseResourceForThreadLite didn't always properly set the ResourceOwnedExclusive
flag, and didn't validate ownership.
- ExSetResourceOwnerPointer wouldn't set the owner if there wasn't one already.
Modified:
trunk/reactos/ntoskrnl/ex/resource.c
trunk/reactos/ntoskrnl/include/internal/ex.h
Modified: trunk/reactos/ntoskrnl/ex/resource.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/resource.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/resource.c (original)
+++ trunk/reactos/ntoskrnl/ex/resource.c Wed May 9 01:35:10 2007
@@ -1,19 +1,17 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ex/resource.c
- * PURPOSE: ERESOURCE Implementation
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
+ * PURPOSE: Executive Resource Implementation
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
*/
-/* WARNING:
+/*
+ * WARNING:
* This implementation is the Windows NT 5.x one.
- * NT 6.0 beta has optimized the OwnerThread entry array
- * and the internals of ExpFindEntryForThread and ExpFindFreeEntry
- * need to be modified accordingly in order to support the WDK.
- * These changes will not be made here until NT 6.0 reaches RTM status since
- * there is a possibility that they will be removed; as such, do NOT
- * update ERESOURCE/relevant code to the WDK definition.
+ * Vista has optimized the OwnerThread entry array and the internals of
+ * ExpFindEntryForThread and ExpFindFreeEntry probably need to be modified
+ * accordingly in order to support the WDK.
*/
/* INCLUDES *****************************************************************/
@@ -26,15 +24,65 @@
#define IsExclusiveWaiting(r) (r->NumberOfExclusiveWaiters)
#define IsSharedWaiting(r) (r->NumberOfSharedWaiters)
#define IsOwnedExclusive(r) (r->Flag & ResourceOwnedExclusive)
-#define IsBoostAllowed(r) (r->Flag & ResourceHasDisabledPriorityBoost)
+#define IsBoostAllowed(r) (!(r->Flag & ResourceHasDisabledPriorityBoost))
+
+#if (!(defined(CONFIG_SMP)) && !(defined(DBG)))
+
+VOID
+FORCEINLINE
+ExAcquireResourceLock(IN PERESOURCE_XP Resource,
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ UNREFERENCED_PARAMETER(Resource);
+ UNREFERENCED_PARAMETER(LockHandle);
+
+ /* Simply disable interrupts */
+ _disable();
+}
+
+VOID
+FORCEINLINE
+ExReleaseResourceLock(IN PERESOURCE_XP Resource,
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ UNREFERENCED_PARAMETER(Resource);
+ UNREFERENCED_PARAMETER(LockHandle);
+
+ /* Simply enable interrupts */
+ _disable();
+}
+
+#else
+
+VOID
+FORCEINLINE
+ExAcquireResourceLock(IN PERESOURCE_XP Resource,
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ /* Acquire the lock */
+ KeAcquireInStackQueuedSpinLock(&Resource->SpinLock, LockHandle);
+}
+
+VOID
+FORCEINLINE
+ExReleaseResourceLock(IN PERESOURCE_XP Resource,
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ UNREFERENCED_PARAMETER(Resource);
+
+ /* Release the lock */
+ KeReleaseInStackQueuedSpinLock(LockHandle);
+}
+#endif
/* DATA***********************************************************************/
+LARGE_INTEGER ExShortTime = {{-100000, -1}};
LARGE_INTEGER ExpTimeout;
ULONG ExpResourceTimeoutCount = 90 * 3600 / 2;
KSPIN_LOCK ExpResourceSpinLock;
LIST_ENTRY ExpSystemResourcesList;
-BOOLEAN ExResourceStrict = FALSE; /* FIXME */
+BOOLEAN ExResourceStrict = TRUE;
/* PRIVATE FUNCTIONS *********************************************************/
@@ -74,8 +122,8 @@
* The ExpCheckForApcsDisabled routine checks if Kernel APCs are still
* enabled when they should be disabled, and optionally breakpoints.
*
- * @param BreakIfTrue
- * Specifies if we should break if an invalid APC State is detected.
+ * @param Irql
+ * Specifies the IRQL during the acquire attempt.
*
* @param Resource
* Pointer to the resource being checked.
@@ -90,15 +138,15 @@
*--*/
VOID
NTAPI
-ExpCheckForApcsDisabled(IN BOOLEAN BreakIfTrue,
+ExpCheckForApcsDisabled(IN KIRQL Irql,
IN PERESOURCE_XP Resource,
- IN PETHREAD Thread)
+ IN PKTHREAD Thread)
{
/* Check if we should care and check if we should break */
if ((ExResourceStrict) &&
- (BreakIfTrue) &&
- !(Thread->SystemThread) &&
- !(Thread->Tcb.CombinedApcDisable))
+ (Irql >= APC_LEVEL) &&
+ !(((PETHREAD)Thread)->SystemThread) &&
+ !(Thread->CombinedApcDisable))
{
/* Bad! */
DPRINT1("EX: resource: APCs still enabled before resource %p acquire "
@@ -143,8 +191,8 @@
* @param Resource
* Pointer to the resource.
*
- * @param OldIrql
- * Pointer to current IRQL. TBC: Pointer to in-stack queued spinlock.
+ * @param LockHandle
+ * Pointer to in-stack queued spinlock.
*
* @return None.
*
@@ -154,33 +202,44 @@
VOID
NTAPI
ExpAllocateExclusiveWaiterEvent(IN PERESOURCE_XP Resource,
- IN PKIRQL OldIrql)
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
{
PKEVENT Event;
/* Release the lock */
- ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
-
- /* Allocate the event */
- Event = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(KEVENT),
- TAG_RESOURCE_EVENT);
-
- /* Initialize it */
- KeInitializeEvent(Event, SynchronizationEvent, FALSE);
-
- /* Set it */
- if (InterlockedCompareExchangePointer(&Resource->ExclusiveWaiters,
- Event,
- NULL))
- {
- /* Someone already set it, free our event */
- DPRINT1("WARNING: Handling race condition\n");
- ExFreePool(Event);
- }
+ ExReleaseResourceLock(Resource, LockHandle);
+
+ /* Loop as long as we keep running out of memory */
+ do
+ {
+ /* Allocate the event */
+ Event = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(KEVENT),
+ TAG_RESOURCE_EVENT);
+ if (Event)
+ {
+ /* Initialize it */
+ KeInitializeEvent(Event, SynchronizationEvent, FALSE);
+
+ /* Set it */
+ if (InterlockedCompareExchangePointer(&Resource->ExclusiveWaiters,
+ Event,
+ NULL))
+ {
+ /* Someone already set it, free our event */
+ DPRINT1("WARNING: Handling race condition\n");
+ ExFreePool(Event);
+ }
+
+ break;
+ }
+
+ /* Wait a bit before trying again */
+ KeDelayExecutionThread(KernelMode, FALSE, &ExShortTime);
+ } while (TRUE);
/* Re-acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, OldIrql);
+ ExAcquireResourceLock(Resource, LockHandle);
}
/*++
@@ -192,8 +251,8 @@
* @param Resource
* Pointer to the resource.
*
- * @param OldIrql
- * Pointer to current IRQL. TBC: Pointer to in-stack queued spinlock.
+ * @param LockHandle
+ * Pointer to in-stack queued spinlock.
*
* @return None.
*
@@ -203,33 +262,44 @@
VOID
NTAPI
ExpAllocateSharedWaiterSemaphore(IN PERESOURCE_XP Resource,
- IN PKIRQL OldIrql)
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
{
PKSEMAPHORE Semaphore;
/* Release the lock */
- ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
-
- /* Allocate the semaphore */
- Semaphore = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(KSEMAPHORE),
- TAG_RESOURCE_SEMAPHORE);
-
- /* Initialize it */
- KeInitializeSemaphore(Semaphore, 0, MAXLONG);
-
- /* Set it */
- if (InterlockedCompareExchangePointer(&Resource->SharedWaiters,
- Semaphore,
- NULL))
- {
- /* Someone already set it, free our semaphore */
- DPRINT1("WARNING: Handling race condition\n");
- ExFreePool(Semaphore);
- }
+ ExReleaseResourceLock(Resource, LockHandle);
+
+ /* Loop as long as we keep running out of memory */
+ do
+ {
+ /* Allocate the semaphore */
+ Semaphore = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(KSEMAPHORE),
+ TAG_RESOURCE_SEMAPHORE);
+ if (Semaphore)
+ {
+ /* Initialize it */
+ KeInitializeSemaphore(Semaphore, 0, MAXLONG);
+
+ /* Set it */
+ if (InterlockedCompareExchangePointer(&Resource->SharedWaiters,
+ Semaphore,
+ NULL))
+ {
+ /* Someone already set it, free our semaphore */
+ DPRINT1("WARNING: Handling race condition\n");
+ ExFreePool(Semaphore);
+ }
+
+ break;
+ }
+
+ /* Wait a bit before trying again */
+ KeDelayExecutionThread(KernelMode, FALSE, &ExShortTime);
+ } while (TRUE);
/* Re-acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, OldIrql);
+ ExAcquireResourceLock(Resource, LockHandle);
}
/*++
@@ -241,8 +311,8 @@
* @param Resource
* Pointer to the resource.
*
- * @param OldIrql
- * Pointer to current IRQL. TBC: Pointer to in-stack queued spinlock.
+ * @param LockHandle
+ * Pointer to in-stack queued spinlock.
*
* @return None.
*
@@ -252,12 +322,11 @@
VOID
NTAPI
ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource,
- IN PKIRQL OldIrql)
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
{
POWNER_ENTRY Owner, Table;
- KIRQL OldIrql2;
+ KIRQL OldIrql;
ULONG NewSize, OldSize;
- DPRINT("ExpExpandResourceOwnerTable: %p\n", Resource);
/* Get the owner table */
Owner = Resource->OwnerTable;
@@ -275,7 +344,7 @@
}
/* Release the lock */
- ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
+ ExReleaseResourceLock(Resource, LockHandle);
/* Allocate memory for the table */
Table = ExAllocatePoolWithTag(NonPagedPool,
@@ -287,38 +356,36 @@
(NewSize - OldSize) * sizeof(OWNER_ENTRY));
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, OldIrql);
+ ExAcquireResourceLock(Resource, LockHandle);
/* Make sure nothing has changed */
if ((Owner != Resource->OwnerTable) ||
- ((Owner) && (OldSize != Resource->OwnerTable->TableSize)))
+ ((Owner) && (OldSize != Owner->TableSize)))
{
/* Resource changed while we weren't holding the lock; bail out */
- ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
+ ExReleaseResourceLock(Resource, LockHandle);
ExFreePool(Table);
}
else
{
/* Copy the table */
- RtlCopyMemory(Table,
- Owner,
- OldSize * sizeof(OWNER_ENTRY));
+ RtlCopyMemory(Table, Owner, OldSize * sizeof(OWNER_ENTRY));
/* Acquire dispatcher lock to prevent thread boosting */
- OldIrql2 = KiAcquireDispatcherLock();
+ OldIrql = KiAcquireDispatcherLock();
/* Set the new table data */
Table->TableSize = NewSize;
Resource->OwnerTable = Table;
/* Release dispatcher lock */
- KiReleaseDispatcherLock(OldIrql2);
+ KiReleaseDispatcherLock(OldIrql);
/* Sanity check */
ExpVerifyResource(Resource);
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, *OldIrql);
+ ExReleaseResourceLock(Resource, LockHandle);
/* Free the old table */
if (Owner) ExFreePool(Owner);
@@ -331,7 +398,7 @@
KeGetCurrentThread()->ResourceIndex = (UCHAR)OldSize;
/* Lock the resource again */
- ExAcquireResourceLock(&Resource->SpinLock, OldIrql);
+ ExAcquireResourceLock(Resource, LockHandle);
}
/*++
@@ -344,8 +411,8 @@
* @param Resource
* Pointer to the resource.
*
- * @param OldIrql
- * Pointer to current IRQL. TBC: Pointer to in-stack queued spinlock.
+ * @param LockHandle
+ * Pointer to in-stack queued spinlock.
*
* @return Pointer to an empty OWNER_ENTRY structure.
*
@@ -355,13 +422,13 @@
POWNER_ENTRY
FASTCALL
ExpFindFreeEntry(IN PERESOURCE_XP Resource,
- IN PKIRQL OldIrql)
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
{
POWNER_ENTRY Owner, Limit;
POWNER_ENTRY FreeEntry = NULL;
/* Sanity check */
- ASSERT(OldIrql != 0);
+ ASSERT(LockHandle != 0);
ASSERT(Resource->OwnerThreads[0].OwnerThread != 0);
/* Check if the next built-in entry is free */
@@ -385,9 +452,8 @@
if (!Owner->OwnerThread)
{
/* Update the resource entry and return it */
- KeGetCurrentThread()->ResourceIndex = (UCHAR)(Owner -
- Resource->
- OwnerTable);
+ KeGetCurrentThread()->ResourceIndex =
+ (UCHAR)(Owner - Resource->OwnerTable);
return Owner;
}
@@ -397,8 +463,7 @@
}
/* No free entry, expand the table */
- ExpExpandResourceOwnerTable(Resource, OldIrql);
- FreeEntry = NULL;
+ ExpExpandResourceOwnerTable(Resource, LockHandle);
}
/* Return the entry found */
@@ -418,8 +483,8 @@
* @param Thread
* Pointer to the thread to find.
*
- * @param OldIrql
- * Pointer to current IRQL. TBC: Pointer to in-stack queued spinlock.
+ * @param LockHandle
+ * Pointer to in-stack queued spinlock.
*
* @return Pointer to an empty OWNER_ENTRY structure.
*
@@ -430,7 +495,7 @@
FASTCALL
ExpFindEntryForThread(IN PERESOURCE_XP Resource,
IN ERESOURCE_THREAD Thread,
- IN PKIRQL OldIrql)
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
{
POWNER_ENTRY FreeEntry, Owner, Limit;
@@ -456,9 +521,8 @@
if (Owner->OwnerThread == Thread)
{
/* We did, update the index and return it */
- KeGetCurrentThread()->ResourceIndex = (UCHAR)(Owner -
- Resource->
- OwnerTable);
+ KeGetCurrentThread()->ResourceIndex =
+ (UCHAR)(Owner - Resource->OwnerTable);
return Owner;
}
@@ -469,19 +533,19 @@
}
/* Check if it's OK to do an expansion */
- if (!OldIrql) return NULL;
+ if (!LockHandle) return NULL;
/* If we found a free entry by now, return it */
if (FreeEntry)
{
/* Set the resource index */
- KeGetCurrentThread()->ResourceIndex = (UCHAR)(FreeEntry -
- Resource->OwnerTable);
+ KeGetCurrentThread()->ResourceIndex =
+ (UCHAR)(FreeEntry - Resource->OwnerTable);
return FreeEntry;
}
/* No free entry, expand the table */
- ExpExpandResourceOwnerTable(Resource, OldIrql);
+ ExpExpandResourceOwnerTable(Resource, LockHandle);
return NULL;
}
@@ -561,7 +625,7 @@
LARGE_INTEGER Timeout;
PKTHREAD Thread, OwnerThread;
#if DBG
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
#endif
/* Increase contention count and use a 5 second timeout */
@@ -588,7 +652,7 @@
WaitCount = 0;
#if DBG
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Dump debug information */
DPRINT1("Resource @ %lx\n", Resource);
@@ -625,7 +689,7 @@
/* Break */
DbgBreakPoint();
DPRINT1("EX - Rewaiting\n");
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
#endif
}
@@ -709,10 +773,10 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireResourceExclusiveLite(PERESOURCE resource,
- BOOLEAN Wait)
-{
- KIRQL OldIrql = PASSIVE_LEVEL;
+ExAcquireResourceExclusiveLite(IN PERESOURCE resource,
+ IN BOOLEAN Wait)
+{
+ KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
BOOLEAN Success;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -728,8 +792,8 @@
ExpVerifyResource(Resource);
/* Acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
- ExpCheckForApcsDisabled(TRUE, Resource, (PETHREAD)Thread);
+ ExAcquireResourceLock(Resource, &LockHandle);
+ ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
/* Check if there is a shared owner or exclusive owner */
TryAcquire:
@@ -760,20 +824,19 @@
if (!Resource->ExclusiveWaiters)
{
/* It doesn't, allocate the event and try acquiring again */
- ExpAllocateExclusiveWaiterEvent(Resource, &OldIrql);
+ ExpAllocateExclusiveWaiterEvent(Resource, &LockHandle);
goto TryAcquire;
}
- else
- {
- /* Has exclusive waiters, wait on it */
- Resource->NumberOfExclusiveWaiters++;
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
- ExpWaitForResource(Resource, Resource->ExclusiveWaiters);
-
- /* Set owner and return success */
- Resource->OwnerThreads[0].OwnerThread =
ExGetCurrentResourceThread();
- return TRUE;
- }
+
+ /* Has exclusive waiters, wait on it */
+ Resource->NumberOfExclusiveWaiters++;
+ ExReleaseResourceLock(Resource, &LockHandle);
+ ExpWaitForResource(Resource, Resource->ExclusiveWaiters);
+
+ /* Set owner and return success */
+ Resource->OwnerThreads[0].OwnerThread =
+ ExGetCurrentResourceThread();
+ return TRUE;
}
}
}
@@ -788,7 +851,7 @@
}
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return Success;
}
@@ -824,10 +887,10 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireResourceSharedLite(PERESOURCE resource,
- BOOLEAN Wait)
-{
- KIRQL OldIrql;
+ExAcquireResourceSharedLite(IN PERESOURCE resource,
+ IN BOOLEAN Wait)
+{
+ KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -840,8 +903,8 @@
ExpVerifyResource(Resource);
/* Acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
- ExpCheckForApcsDisabled(TRUE, Resource, (PETHREAD)Thread);
+ ExAcquireResourceLock(Resource, &LockHandle);
+ ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
/* See if nobody owns us */
TryAcquire:
@@ -854,7 +917,7 @@
Resource->ActiveCount = 1;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -868,18 +931,18 @@
Resource->OwnerThreads[0].OwnerCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
/* Find a free entry */
- Owner = ExpFindFreeEntry(Resource, &OldIrql);
+ Owner = ExpFindFreeEntry(Resource, &LockHandle);
if (!Owner) goto TryAcquire;
}
else
{
/* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &OldIrql);
+ Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
if (!Owner) goto TryAcquire;
/* Is it us? */
@@ -890,7 +953,7 @@
ASSERT(Owner->OwnerCount != 0);
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -903,7 +966,7 @@
Resource->ActiveCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
}
@@ -912,7 +975,7 @@
if (!Wait)
{
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return FALSE;
}
@@ -920,7 +983,7 @@
if (!Resource->SharedWaiters)
{
/* Allocate it and try another acquire */
- ExpAllocateSharedWaiterSemaphore(Resource, &OldIrql);
+ ExpAllocateSharedWaiterSemaphore(Resource, &LockHandle);
goto TryAcquire;
}
@@ -930,7 +993,7 @@
Resource->NumberOfSharedWaiters++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
ExpWaitForResource(Resource, Resource->SharedWaiters);
return TRUE;
}
@@ -975,10 +1038,10 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireSharedStarveExclusive(PERESOURCE resource,
- BOOLEAN Wait)
-{
- KIRQL OldIrql;
+ExAcquireSharedStarveExclusive(IN PERESOURCE resource,
+ IN BOOLEAN Wait)
+{
+ KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -991,7 +1054,7 @@
ExpVerifyResource(Resource);
/* Acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* See if nobody owns us */
TryAcquire:
@@ -1003,7 +1066,7 @@
Resource->OwnerThreads[1].OwnerCount = 1;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1017,18 +1080,18 @@
Resource->OwnerThreads[0].OwnerCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
/* Find a free entry */
- Owner = ExpFindFreeEntry(Resource, &OldIrql);
+ Owner = ExpFindFreeEntry(Resource, &LockHandle);
if (!Owner) goto TryAcquire;
}
else
{
/* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &OldIrql);
+ Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
if (!Owner) goto TryAcquire;
/* Is it us? */
@@ -1039,7 +1102,7 @@
ASSERT(Owner->OwnerCount != 0);
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1049,7 +1112,7 @@
Resource->ActiveCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1057,8 +1120,16 @@
if (!Wait)
{
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
+ }
+
+ /* Check if we have a shared waiters semaphore */
+ if (!Resource->SharedWaiters)
+ {
+ /* Allocate it and try another acquire */
+ ExpAllocateSharedWaiterSemaphore(Resource, &LockHandle);
+ goto TryAcquire;
}
/* Now wait for the resource */
@@ -1067,7 +1138,7 @@
Resource->NumberOfSharedWaiters++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
ExpWaitForResource(Resource, Resource->SharedWaiters);
return TRUE;
}
@@ -1108,7 +1179,7 @@
ExAcquireSharedWaitForExclusive(IN PERESOURCE resource,
IN BOOLEAN Wait)
{
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -1121,7 +1192,7 @@
ExpVerifyResource(Resource);
/* Acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* See if nobody owns us */
TryAcquire:
@@ -1133,7 +1204,7 @@
Resource->OwnerThreads[1].OwnerCount = 1;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1147,12 +1218,12 @@
Resource->OwnerThreads[0].OwnerCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
/* Find a free entry */
- Owner = ExpFindFreeEntry(Resource, &OldIrql);
+ Owner = ExpFindFreeEntry(Resource, &LockHandle);
if (!Owner) goto TryAcquire;
}
else
@@ -1164,7 +1235,7 @@
if (!Wait)
{
/* So bail out if we're not allowed */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1172,20 +1243,20 @@
if (!Resource->SharedWaiters)
{
/* Allocate one and try again */
- ExpAllocateSharedWaiterSemaphore(Resource, &OldIrql);
+ ExpAllocateSharedWaiterSemaphore(Resource, &LockHandle);
goto TryAcquire;
}
/* Now wait for the resource */
Resource->NumberOfSharedWaiters++;
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
ExpWaitForResource(Resource, Resource->SharedWaiters);
/* Get the lock back */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Find who owns it now */
- while (!(Owner = ExpFindEntryForThread(Resource, Thread, &OldIrql)));
+ while (!(Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle)));
/* Sanity checks */
ASSERT(IsOwnedExclusive(Resource) == FALSE);
@@ -1197,13 +1268,13 @@
Owner->OwnerCount = 1;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
else
{
/* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &OldIrql);
+ Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
if (!Owner) goto TryAcquire;
/* Is it us? */
@@ -1214,7 +1285,7 @@
ASSERT(Owner->OwnerCount != 0);
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1224,7 +1295,7 @@
Resource->ActiveCount++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
}
@@ -1233,7 +1304,7 @@
if (!Wait)
{
/* So bail out if we're not allowed */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
}
@@ -1241,7 +1312,7 @@
if (!Resource->SharedWaiters)
{
/* Allocate one and try again */
- ExpAllocateSharedWaiterSemaphore(Resource, &OldIrql);
+ ExpAllocateSharedWaiterSemaphore(Resource,&LockHandle);
goto TryAcquire;
}
@@ -1251,7 +1322,7 @@
Resource->NumberOfSharedWaiters++;
/* Release the lock and return */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
ExpWaitForResource(Resource, Resource->SharedWaiters);
return TRUE;
}
@@ -1274,10 +1345,10 @@
*--*/
VOID
NTAPI
-ExConvertExclusiveToSharedLite(PERESOURCE resource)
+ExConvertExclusiveToSharedLite(IN PERESOURCE resource)
{
ULONG OldWaiters;
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity checks */
@@ -1287,7 +1358,7 @@
ASSERT(Resource->OwnerThreads[0].OwnerThread ==
(ERESOURCE_THREAD)PsGetCurrentThread());
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Erase the exclusive flag */
Resource->Flag &= ~ResourceOwnedExclusive;
@@ -1301,13 +1372,13 @@
Resource->NumberOfSharedWaiters = 0;
/* Release lock and wake the waiters */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeReleaseSemaphore(Resource->SharedWaiters, 0, OldWaiters, FALSE);
}
else
{
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
}
@@ -1329,9 +1400,9 @@
*--*/
NTSTATUS
NTAPI
-ExDeleteResourceLite(PERESOURCE resource)
-{
- KIRQL OldIrql;
+ExDeleteResourceLite(IN PERESOURCE resource)
+{
+ KLOCK_QUEUE_HANDLE LockHandle;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity checks */
@@ -1341,13 +1412,13 @@
ExpVerifyResource(Resource);
/* Lock the resource */
- KeAcquireSpinLock(&ExpResourceSpinLock, &OldIrql);
+ KeAcquireInStackQueuedSpinLock(&ExpResourceSpinLock, &LockHandle);
/* Remove the resource */
RemoveEntryList(&Resource->SystemResourcesList);
/* Release the lock */
- KeReleaseSpinLock(&ExpResourceSpinLock, OldIrql);
+ KeReleaseInStackQueuedSpinLock(&LockHandle);
/* Free every structure */
if (Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
@@ -1375,22 +1446,22 @@
*--*/
VOID
NTAPI
-ExDisableResourceBoostLite(PERESOURCE resource)
-{
- KIRQL OldIrql;
+ExDisableResourceBoostLite(IN PERESOURCE resource)
+{
+ KLOCK_QUEUE_HANDLE LockHandle;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ExpVerifyResource(Resource);
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Remove the flag */
Resource->Flag |= ResourceHasDisabledPriorityBoost;
/* Release the lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
/*++
@@ -1410,7 +1481,7 @@
*--*/
ULONG
NTAPI
-ExGetExclusiveWaiterCount(PERESOURCE resource)
+ExGetExclusiveWaiterCount(IN PERESOURCE resource)
{
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -1435,7 +1506,7 @@
*--*/
ULONG
NTAPI
-ExGetSharedWaiterCount(PERESOURCE resource)
+ExGetSharedWaiterCount(IN PERESOURCE resource)
{
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -1461,9 +1532,10 @@
*--*/
NTSTATUS
NTAPI
-ExInitializeResourceLite(PERESOURCE resource)
+ExInitializeResourceLite(IN PERESOURCE resource)
{
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
+ KLOCK_QUEUE_HANDLE LockHandle;
/* Clear the structure */
RtlZeroMemory(Resource, sizeof(ERESOURCE_XP));
@@ -1472,9 +1544,9 @@
KeInitializeSpinLock(&Resource->SpinLock);
/* Add it into the system list */
- ExInterlockedInsertTailList(&ExpSystemResourcesList,
- &Resource->SystemResourcesList,
- &ExpResourceSpinLock);
+ KeAcquireInStackQueuedSpinLock(&ExpResourceSpinLock, &LockHandle);
+ InsertTailList(&ExpSystemResourcesList, &Resource->SystemResourcesList);
+ KeReleaseInStackQueuedSpinLock(&LockHandle);
/* Return success */
return STATUS_SUCCESS;
@@ -1498,7 +1570,7 @@
*--*/
BOOLEAN
NTAPI
-ExIsResourceAcquiredExclusiveLite(PERESOURCE resource)
+ExIsResourceAcquiredExclusiveLite(IN PERESOURCE resource)
{
ERESOURCE_THREAD Thread = ExGetCurrentResourceThread();
BOOLEAN IsAcquired = FALSE;
@@ -1544,13 +1616,16 @@
ERESOURCE_THREAD Thread;
ULONG i, Size;
ULONG Count = 0;
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ExpVerifyResource(Resource);
+ /* Check if nobody owns us */
+ if (!Resource->ActiveCount) return 0;
+
/* Get the thread */
Thread = ExGetCurrentResourceThread();
@@ -1560,50 +1635,57 @@
/* Found it, return count */
Count = Resource->OwnerThreads[0].OwnerCount;
}
- else if (Resource->OwnerThreads[1].OwnerThread == Thread)
- {
- /* Found it on the second list, return count */
- Count = Resource->OwnerThreads[1].OwnerCount;
- }
else
{
- /* Not in the list, do a full table look up */
- Owner = Resource->OwnerTable;
- if (Owner)
+ /* We can't own an exclusive resource at this point */
+ if (IsOwnedExclusive(Resource)) return 0;
+
+ /* Check if we are in the other thread list */
+ if (Resource->OwnerThreads[1].OwnerThread == Thread)
+ {
+ /* Found it on the second list, return count */
+ Count = Resource->OwnerThreads[1].OwnerCount;
+ }
+ else
{
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
-
- /* Get the resource index */
- i = ((PKTHREAD)Thread)->ResourceIndex;
- Size = Owner->TableSize;
-
- /* Check if the index is valid and check if we don't match */
- if ((i >= Size) || (Owner[i].OwnerThread != Thread))
+ ExAcquireResourceLock(Resource, &LockHandle);
+
+ /* Not in the list, do a full table look up */
+ Owner = Resource->OwnerTable;
+ if (Owner)
{
- /* Sh*t! We need to do a full search */
- for (i = 1; i < Size; i++)
+ /* Get the resource index */
+ i = ((PKTHREAD)Thread)->ResourceIndex;
+ Size = Owner->TableSize;
+
+ /* Check if the index is valid and check if we don't match */
+ if ((i >= Size) || (Owner[i].OwnerThread != Thread))
{
- /* Move to next owner */
- Owner++;
-
- /* Try to find a match */
- if (Owner->OwnerThread == Thread)
+ /* Sh*t! We need to do a full search */
+ for (i = 1; i < Size; i++)
{
- /* Finally! */
- Count = Owner->OwnerCount;
- break;
+ /* Move to next owner */
+ Owner++;
+
+ /* Try to find a match */
+ if (Owner->OwnerThread == Thread)
+ {
+ /* Finally! */
+ Count = Owner->OwnerCount;
+ break;
+ }
}
}
+ else
+ {
+ /* We found the match directlry */
+ Count = Owner[i].OwnerCount;
+ }
}
- else
- {
- /* We found the match directlry */
- Count = Owner[i].OwnerCount;
- }
/* Release the lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
}
@@ -1637,7 +1719,7 @@
*--*/
NTSTATUS
NTAPI
-ExReinitializeResourceLite(PERESOURCE resource)
+ExReinitializeResourceLite(IN PERESOURCE resource)
{
PKEVENT Event;
PKSEMAPHORE Semaphore;
@@ -1679,9 +1761,6 @@
Resource->ContentionCount = 0;
Resource->NumberOfSharedWaiters = 0;
Resource->NumberOfExclusiveWaiters = 0;
-
- /* Reset the spinlock */
- KeInitializeSpinLock(&Resource->SpinLock);
return STATUS_SUCCESS;
}
@@ -1703,11 +1782,11 @@
*--*/
VOID
FASTCALL
-ExReleaseResourceLite(PERESOURCE resource)
+ExReleaseResourceLite(IN PERESOURCE resource)
{
ERESOURCE_THREAD Thread;
ULONG Count, i;
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner, Limit;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -1716,19 +1795,18 @@
/* Get the thread and lock the resource */
Thread = ExGetCurrentResourceThread();
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
- ExpCheckForApcsDisabled(TRUE, Resource, (PETHREAD)Thread);
+ ExAcquireResourceLock(Resource, &LockHandle);
+ ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
/* Check if it's exclusively owned */
if (IsOwnedExclusive(Resource))
{
/* Decrement owner count and check if we're done */
ASSERT(Resource->OwnerThreads[0].OwnerCount > 0);
- ASSERT(Resource->ActiveCount == 1);
if (--Resource->OwnerThreads[0].OwnerCount)
{
/* Done, release lock! */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return;
}
@@ -1745,13 +1823,13 @@
/* Remove the exclusive flag */
Resource->Flag &= ~ResourceOwnedExclusive;
- /* Give ownage to another thread */
+ /* Give ownership to another thread */
Count = Resource->NumberOfSharedWaiters;
Resource->ActiveCount = (SHORT)Count;
Resource->NumberOfSharedWaiters = 0;
/* Release lock and let someone else have it */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
return;
}
@@ -1764,7 +1842,7 @@
Resource->NumberOfExclusiveWaiters--;
/* Release the lock and give it away */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeSetEventBoostPriority(Resource->ExclusiveWaiters,
(PKTHREAD*)
&Resource->OwnerThreads[0].OwnerThread);
@@ -1843,7 +1921,7 @@
if (--Owner->OwnerCount)
{
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return;
}
@@ -1865,7 +1943,7 @@
Resource->NumberOfExclusiveWaiters--;
/* Release the lock and give it away */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeSetEventBoostPriority(Resource->ExclusiveWaiters,
(PKTHREAD*)
&Resource->OwnerThreads[0].OwnerThread);
@@ -1875,7 +1953,7 @@
}
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
/*++
@@ -1899,32 +1977,32 @@
*--*/
VOID
NTAPI
-ExReleaseResourceForThreadLite(PERESOURCE resource,
- ERESOURCE_THREAD Thread)
+ExReleaseResourceForThreadLite(IN PERESOURCE resource,
+ IN ERESOURCE_THREAD Thread)
{
ULONG i;
ULONG Count;
- KIRQL OldIrql;
- POWNER_ENTRY Owner;
+ KLOCK_QUEUE_HANDLE LockHandle;
+ POWNER_ENTRY Owner, Limit;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
ASSERT(Thread != 0);
/* Get the thread and lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
-
- /* Sanity check */
+ ExAcquireResourceLock(Resource, &LockHandle);
+
+ /* Sanity checks */
ExpVerifyResource(Resource);
+ ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
/* Check if it's exclusively owned */
if (IsOwnedExclusive(Resource))
{
/* Decrement owner count and check if we're done */
ASSERT(Resource->OwnerThreads[0].OwnerThread == Thread);
- ASSERT(Resource->OwnerThreads[0].OwnerCount > 0);
if (--Resource->OwnerThreads[0].OwnerCount)
{
/* Done, release lock! */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return;
}
@@ -1947,7 +2025,7 @@
Resource->NumberOfSharedWaiters = 0;
/* Release lock and let someone else have it */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
return;
}
@@ -1960,7 +2038,7 @@
Resource->NumberOfExclusiveWaiters--;
/* Release the lock and give it away */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeSetEventBoostPriority(Resource->ExclusiveWaiters,
(PKTHREAD*)
&Resource->OwnerThreads[0].OwnerThread);
@@ -2000,10 +2078,22 @@
if ((i >= Owner->TableSize) || (Owner[i].OwnerThread != Thread))
{
/* Get the last entry */
+ Limit = &Owner[Owner->TableSize];
for (;;)
{
/* Move to the next entry */
Owner++;
+
+ /* Make sure we're not out of bounds */
+ if (Owner >= Limit)
+ {
+ /* Bugcheck, nobody owns us */
+ KeBugCheckEx(RESOURCE_NOT_OWNED,
+ (ULONG_PTR)Resource,
+ (ULONG_PTR)Thread,
+ (ULONG_PTR)Resource->OwnerTable,
+ (ULONG_PTR)3);
+ }
/* Check for a match */
if (Owner->OwnerThread == Thread) break;
@@ -2024,7 +2114,7 @@
if (!(--Owner->OwnerCount))
{
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return;
}
@@ -2039,13 +2129,14 @@
if (IsExclusiveWaiting(Resource))
{
/* Give exclusive access */
+ Resource->Flag |= ResourceOwnedExclusive;
Resource->OwnerThreads[0].OwnerThread = 1;
Resource->OwnerThreads[0].OwnerCount = 1;
Resource->ActiveCount = 1;
Resource->NumberOfExclusiveWaiters--;
/* Release the lock and give it away */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
KeSetEventBoostPriority(Resource->ExclusiveWaiters,
(PKTHREAD*)
&Resource->OwnerThreads[0].OwnerThread);
@@ -2055,7 +2146,7 @@
}
/* Release lock */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
/*++
@@ -2093,7 +2184,7 @@
IN PVOID OwnerPointer)
{
ERESOURCE_THREAD Thread;
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner, ThisOwner;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -2107,7 +2198,7 @@
ExpVerifyResource(Resource);
/* Lock the resource */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Check if it's exclusive */
if (IsOwnedExclusive(Resource))
@@ -2121,8 +2212,8 @@
{
/* Set the thread in both entries */
ThisOwner = ExpFindEntryForThread(Resource,
- (ERESOURCE_THREAD)OwnerPointer,
- 0);
+ (ERESOURCE_THREAD)OwnerPointer,
+ 0);
Owner = ExpFindEntryForThread(Resource, Thread, 0);
if (!Owner)
{
@@ -2144,10 +2235,15 @@
ASSERT(Resource->ActiveCount >= 2);
Resource->ActiveCount--;
}
+ else
+ {
+ /* Update the owner entry instead */
+ Owner->OwnerThread = (ERESOURCE_THREAD)OwnerPointer;
+ }
}
/* Release the resource */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
}
/*++
@@ -2168,10 +2264,10 @@
*--*/
BOOLEAN
NTAPI
-ExTryToAcquireResourceExclusiveLite(PERESOURCE resource)
+ExTryToAcquireResourceExclusiveLite(IN PERESOURCE resource)
{
ERESOURCE_THREAD Thread;
- KIRQL OldIrql;
+ KLOCK_QUEUE_HANDLE LockHandle;
BOOLEAN Acquired = FALSE;
PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
@@ -2186,7 +2282,7 @@
ExpVerifyResource(Resource);
/* Acquire the lock */
- ExAcquireResourceLock(&Resource->SpinLock, &OldIrql);
+ ExAcquireResourceLock(Resource, &LockHandle);
/* Check if there is an owner */
if (!Resource->ActiveCount)
@@ -2207,7 +2303,7 @@
}
/* Release the resource */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ ExReleaseResourceLock(Resource, &LockHandle);
return Acquired;
}
@@ -2228,7 +2324,7 @@
*--*/
PVOID
NTAPI
-ExEnterCriticalRegionAndAcquireResourceExclusive(PERESOURCE Resource)
+ExEnterCriticalRegionAndAcquireResourceExclusive(IN PERESOURCE Resource)
{
/* Enter critical region */
KeEnterCriticalRegion();
@@ -2257,7 +2353,7 @@
*--*/
VOID
FASTCALL
-ExReleaseResourceAndLeaveCriticalRegion(PERESOURCE Resource)
+ExReleaseResourceAndLeaveCriticalRegion(IN PERESOURCE Resource)
{
/* Release the resource */
ExReleaseResourceLite(Resource);
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ex.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ex.h Wed May 9 01:35:10 2007
@@ -25,6 +25,7 @@
extern ULONG CmNtCSDVersion;
extern ULONG NtGlobalFlag;
extern ULONG ExpInitializationPhase;
+extern ULONG ExpAltTimeZoneBias;
typedef struct _EXHANDLE
{
@@ -61,18 +62,6 @@
#define MAX_FAST_REFS 7
-/* Note: we only use a spinlock on SMP. On UP, we cli/sti intead */
-#ifndef CONFIG_SMP
-#define ExAcquireResourceLock(l, i) { \
- (void)i; \
- _disable(); \
-}
-#define ExReleaseResourceLock(l, i) _enable();
-#else
-#define ExAcquireResourceLock(l, i) KeAcquireSpinLock(l, i);
-#define ExReleaseResourceLock(l, i) KeReleaseSpinLock(l, i);
-#endif
-
#define ExAcquireRundownProtection _ExAcquireRundownProtection
#define ExReleaseRundownProtection _ExReleaseRundownProtection
#define ExInitializeRundownProtection _ExInitializeRundownProtection
@@ -1012,6 +1001,18 @@
NTAPI
ExTimerRundown(VOID);
+VOID
+NTAPI
+HeadlessInit(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+VOID
+NTAPI
+XIPInit(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
#define InterlockedDecrementUL(Addend) \
(ULONG)InterlockedDecrement((PLONG)(Addend))