--- trunk/reactos/ntoskrnl/ex/resource.c 2006-01-11 22:40:31 UTC (rev 20792)
+++ trunk/reactos/ntoskrnl/ex/resource.c 2006-01-11 23:22:15 UTC (rev 20793)
@@ -535,6 +535,11 @@
* @remarks None.
*
*--*/
+#if 0
+
+/*
+ * Disabled, read the comments bellow.
+ */
VOID
FASTCALL
ExpBoostOwnerThread(IN PKTHREAD Thread,
@@ -570,6 +575,7 @@
}
}
}
+#endif
/*++
* @name ExpWaitForResource
@@ -596,7 +602,6 @@
ULONG Size, WaitCount = 0;
KIRQL OldIrql;
POWNER_ENTRY Owner;
- PKTHREAD OwnerThread, Thread;
NTSTATUS Status;
LARGE_INTEGER Timeout;
@@ -664,10 +669,20 @@
ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
#endif
}
+#if 0
+/*
+ * Disabled because:
+ * - We cannot access the OwnerTable without locking the resource.
+ * - The shared waiters may wait also on the semaphore. It makes no sense to boost a waiting thread.
+ * - The thread header is initialized like KeWaitForSingleObject (?, ?, ?, TRUE, ?).
+ * During the boost, possible the dispatcher lock is released but the thread block (WaitNext) isn't changed.
+ */
/* Check if we can boost */
if (!(Resource->Flag & ResourceHasDisabledPriorityBoost))
{
+ PKTHREAD Thread, OwnerThread;
+
/* Get the current kernel thread and lock the dispatcher */
Thread = KeGetCurrentThread();
Thread->WaitIrql = KeAcquireDispatcherDatabaseLock();
@@ -700,6 +715,7 @@
}
}
}
+#endif
}
}
@@ -881,10 +897,20 @@
Resource, Wait);
if (!Resource->ActiveCount)
{
- /* Nobody owns it, so let's take control */
+ if (Resource->NumberOfSharedWaiters == 0)
+ {
+ Owner = &Resource->OwnerThreads[1];
+ }
+ else
+ {
+ /* Find a free entry */
+ Owner = ExpFindFreeEntry(Resource, &OldIrql);
+ if (!Owner) goto TryAcquire;
+ }
+
+ Owner->OwnerThread = Thread;
+ Owner->OwnerCount = 1;
Resource->ActiveCount = 1;
- Resource->OwnerThreads[1].OwnerThread = Thread;
- Resource->OwnerThreads[1].OwnerCount = 1;
/* Release the lock and return */
ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
@@ -946,7 +972,7 @@
{
/* Release the lock and return */
ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
- return TRUE;
+ return FALSE;
}
/* Check if we have a shared waiters semaphore */
@@ -1769,6 +1795,7 @@
{
/* 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! */
@@ -1779,45 +1806,42 @@
/* Clear the owner */
Resource->OwnerThreads[0].OwnerThread = 0;
- /* See if the resource isn't being owned anymore */
- ASSERT(Resource->ActiveCount > 0);
- if (!(--Resource->ActiveCount))
+ /* Check if there are shared waiters */
+ if (IsSharedWaiting(Resource))
{
- /* Check if there are shared waiters */
- if (IsSharedWaiting(Resource))
- {
- /* Remove the exclusive flag */
- Resource->Flag &= ~ResourceOwnedExclusive;
+ /* Remove the exclusive flag */
+ Resource->Flag &= ~ResourceOwnedExclusive;
- /* Give ownage to another thread */
- Count = Resource->NumberOfSharedWaiters;
- Resource->ActiveCount = (USHORT)Count;
- Resource->NumberOfSharedWaiters = 0;
+ /* Give ownage to another thread */
+ Count = Resource->NumberOfSharedWaiters;
+ Resource->ActiveCount = (USHORT)Count;
+ Resource->NumberOfSharedWaiters = 0;
- /* Release lock and let someone else have it */
- ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
- KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
- return;
- }
- else if (IsExclusiveWaiting(Resource))
- {
- /* Give exclusive access */
- Resource->OwnerThreads[0].OwnerThread = 1;
- Resource->OwnerThreads[0].OwnerCount = 1;
- Resource->ActiveCount = 1;
- Resource->NumberOfExclusiveWaiters--;
+ /* Release lock and let someone else have it */
+ ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
+ return;
+ }
+ else if (IsExclusiveWaiting(Resource))
+ {
+ /* Give exclusive access */
+ 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);
- KeSetEventBoostPriority(Resource->ExclusiveWaiters,
- (PKTHREAD*)
- &Resource->OwnerThreads[0].OwnerThread);
- return;
- }
+ /* Release the lock and give it away */
+ ExReleaseResourceLock(&Resource->SpinLock, OldIrql);
+ KeSetEventBoostPriority(Resource->ExclusiveWaiters,
+ (PKTHREAD*)
+ &Resource->OwnerThreads[0].OwnerThread);
+ return;
+ }
- /* Remove the exclusive flag */
- Resource->Flag &= ~ResourceOwnedExclusive;
- }
+ /* Remove the exclusive flag */
+ Resource->Flag &= ~ResourceOwnedExclusive;
+
+ Resource->ActiveCount = 0;
}
else
{
@@ -1827,11 +1851,6 @@
/* Found it, get owner */
Owner = &Resource->OwnerThreads[1];
}
- else if (Resource->OwnerThreads[0].OwnerThread == Thread)
- {
- /* Found it on the second list, get owner */
- Owner = &Resource->OwnerThreads[0];
- }
else
{
/* Not in the list, do a full table look up */