- Reimplement Fast Mutex implementation in HAL/NT to be compatible with
the real implementation. (Fast Mutex needs to raise IRQL).
- Implement ExEnterCriticalRegionAndAcquireFastMutexUnsafe and
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion.
- Make win32k use those two new functions so that it can continue
running at PASSIVE_LEVEL.
- Remove CcBrokenMutex and use the new APIs instead.
- Implement and export ntoskrnl version of Fast Mutex
- Update headers for new fast-mutex definition and API exports.
- Fix RemoveEntryList in NDK.
- Add exfuncs.h to NDK.
- Fix path in mmtypes.h in NDK to be compatible to how it shoudl be
included.
Modified: trunk/reactos/hal/halx86/generic/fmutex.c
Modified: trunk/reactos/include/ndk/arch/mmtypes.h
Added: trunk/reactos/include/ndk/exfuncs.h
Modified: trunk/reactos/include/ndk/ntndk.h
Modified: trunk/reactos/include/ndk/rtltypes.h
Modified: trunk/reactos/include/win32k/bitmaps.h
Modified: trunk/reactos/ntoskrnl/cc/ccmutex.c
Modified: trunk/reactos/ntoskrnl/cc/fs.c
Modified: trunk/reactos/ntoskrnl/cc/pin.c
Modified: trunk/reactos/ntoskrnl/cc/view.c
Modified: trunk/reactos/ntoskrnl/ex/fmutex.c
Modified: trunk/reactos/ntoskrnl/include/internal/cc.h
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ntoskrnl.def
Modified: trunk/reactos/ntoskrnl/ntoskrnl.xml
Modified: trunk/reactos/subsys/win32k/eng/driverobj.c
Modified: trunk/reactos/subsys/win32k/include/inteng.h
Modified: trunk/reactos/subsys/win32k/include/text.h
Modified: trunk/reactos/subsys/win32k/ntuser/guicheck.c
Modified: trunk/reactos/subsys/win32k/ntuser/monitor.c
Modified: trunk/reactos/subsys/win32k/ntuser/ntuser.c
Modified: trunk/reactos/subsys/win32k/ntuser/ssec.c
Modified: trunk/reactos/subsys/win32k/ntuser/timer.c
Modified: trunk/reactos/w32api/include/ddk/winddk.h
_____
Modified: trunk/reactos/hal/halx86/generic/fmutex.c
--- trunk/reactos/hal/halx86/generic/fmutex.c 2005-11-19 21:07:25 UTC
(rev 19351)
+++ trunk/reactos/hal/halx86/generic/fmutex.c 2005-11-19 22:13:35 UTC
(rev 19352)
@@ -1,54 +1,96 @@
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS HAL
* FILE: ntoskrnl/hal/x86/fmutex.c
- * PURPOSE: Implements fast mutexes
- * PROGRAMMER: David Welch (welch(a)cwcom.net)
- * Eric Kohl (ekohl(a)rz-online.de)
- * UPDATE HISTORY:
- * Created 09/06/2000
+ * PURPOSE: Deprecated HAL Fast Mutex
+ * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
*/
+/*
+ * NOTE: Even HAL itself has #defines to use the Exi* APIs inside
NTOSKRNL.
+ * These are only exported here for compatibility with really old
+ * drivers. Also note that in theory, these can be made much
faster
+ * by using assembly and inlining all the operations, including
+ * raising and lowering irql.
+ */
+
/* INCLUDES
*****************************************************************/
#include <hal.h>
#define NDEBUG
#include <debug.h>
+#undef ExAcquireFastMutex
+#undef ExReleaseFastMutex
+#undef ExTryToAcquireFastMutex
+
/* FUNCTIONS
*****************************************************************/
-#undef KeEnterCriticalRegion
-#undef KeLeaveCriticalRegion
-VOID FASTCALL
-ExAcquireFastMutex (PFAST_MUTEX FastMutex)
+VOID
+FASTCALL
+ExAcquireFastMutex(PFAST_MUTEX FastMutex)
{
- KeEnterCriticalRegion();
- ExAcquireFastMutexUnsafe(FastMutex);
+ KIRQL OldIrql;
+
+ /* Raise IRQL to APC */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /* Decrease the count */
+ if (InterlockedDecrement(&FastMutex->Count))
+ {
+ /* Someone is still holding it, use slow path */
+ FastMutex->Contention++;
+ KeWaitForSingleObject(&FastMutex->Gate,
+ WrExecutive,
+ WaitAny,
+ FALSE,
+ NULL);
+ }
+
+ /* Set the owner and IRQL */
+ FastMutex->Owner = KeGetCurrentThread();
+ FastMutex->OldIrql = OldIrql;
}
+VOID
+FASTCALL
+ExReleaseFastMutex(PFAST_MUTEX FastMutex)
+{
+ /* Erase the owner */
+ FastMutex->Owner = (PVOID)1;
-VOID FASTCALL
-ExReleaseFastMutex (PFAST_MUTEX FastMutex)
-{
- ExReleaseFastMutexUnsafe(FastMutex);
- KeLeaveCriticalRegion();
+ /* Increase the count */
+ if (InterlockedIncrement(&FastMutex->Count) <= 0)
+ {
+ /* Someone was waiting for it, signal the waiter */
+ KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
+ }
+
+ /* Lower IRQL back */
+ KfLowerIrql(FastMutex->OldIrql);
}
+BOOLEAN
+FASTCALL
+ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
+{
+ KIRQL OldIrql;
-BOOLEAN FASTCALL
-ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
-{
- KeEnterCriticalRegion();
- if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+ /* Raise to APC_LEVEL */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /* Check if we can quickly acquire it */
+ if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
{
- FastMutex->Owner = KeGetCurrentThread();
- return(TRUE);
+ /* We have, set us as owners */
+ FastMutex->Owner = KeGetCurrentThread();
+ return TRUE;
}
- else
+ else
{
- KeLeaveCriticalRegion();
- return(FALSE);
+ /* Acquire attempt failed */
+ KfLowerIrql(OldIrql);
+ return FALSE;
}
}
_____
Modified: trunk/reactos/include/ndk/arch/mmtypes.h
--- trunk/reactos/include/ndk/arch/mmtypes.h 2005-11-19 21:07:25 UTC
(rev 19351)
+++ trunk/reactos/include/ndk/arch/mmtypes.h 2005-11-19 22:13:35 UTC
(rev 19352)
@@ -10,7 +10,7 @@
#define _ARCH_MMTYPES_H
#ifdef _M_IX86
-#include <ndk/i386/mmtypes.h>
+#include "./../i386/mmtypes.h"
#else
#error "Unknown processor"
#endif
_____
Added: trunk/reactos/include/ndk/exfuncs.h
--- trunk/reactos/include/ndk/exfuncs.h 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/include/ndk/exfuncs.h 2005-11-19 22:13:35 UTC (rev
19352)
@@ -0,0 +1,26 @@
+/*
+ * PROJECT: ReactOS Native Headers
+ * FILE: include/ndk/exfuncs.h
+ * PURPOSE: Prototypes for exported Executive Functions not
defined in DDK/IFS
+ * PROGRAMMER: Alex Ionescu (alex(a)relsoft.net)
+ * UPDATE HISTORY:
+ * Created 06/10/04
+ */
+#ifndef _EXFUNCS_H
+#define _EXFUNCS_H
+
+/* DEPENDENCIES
**************************************************************/
+
+/* FUNCTION TYPES
************************************************************/
+
+/* PROTOTYPES
****************************************************************/
+
+VOID
+FASTCALL
+ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex);
+
+VOID
+FASTCALL
+ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex);
+
+#endif
_____
Modified: trunk/reactos/include/ndk/ntndk.h
--- trunk/reactos/include/ndk/ntndk.h 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/include/ndk/ntndk.h 2005-11-19 22:13:35 UTC (rev
19352)
@@ -27,6 +27,7 @@
#include "haltypes.h" /* Hardware Abstraction Layer Types */
#include "halfuncs.h" /* Hardware Abstraction Layer Functions */
#include "inbvfuncs.h" /* Initialization Boot Video Functions */
+#include "exfuncs.h" /* Executive Functions */
#include "iofuncs.h" /* Input/Output Manager Functions */
#include "kefuncs.h" /* Kernel Functions */
#include "mmfuncs.h" /* Memory Manager Functions */
_____
Modified: trunk/reactos/include/ndk/rtltypes.h
--- trunk/reactos/include/ndk/rtltypes.h 2005-11-19 21:07:25 UTC
(rev 19351)
+++ trunk/reactos/include/ndk/rtltypes.h 2005-11-19 22:13:35 UTC
(rev 19352)
@@ -175,7 +175,7 @@
OldBlink = Entry->Blink;
OldFlink->Blink = OldBlink;
OldBlink->Flink = OldFlink;
- return (OldFlink == OldBlink);
+ return (BOOLEAN)(OldFlink == OldBlink);
}
static __inline
_____
Modified: trunk/reactos/include/win32k/bitmaps.h
--- trunk/reactos/include/win32k/bitmaps.h 2005-11-19 21:07:25 UTC
(rev 19351)
+++ trunk/reactos/include/win32k/bitmaps.h 2005-11-19 22:13:35 UTC
(rev 19352)
@@ -1,4 +1,3 @@
-
#ifndef __WIN32K_BITMAPS_H
#define __WIN32K_BITMAPS_H
@@ -38,8 +37,8 @@
BOOL INTERNAL_CALL BITMAP_Cleanup(PVOID ObjectBody);
BOOL INTERNAL_CALL BITMAPOBJ_InitBitsLock(BITMAPOBJ *pBMObj);
-#define BITMAPOBJ_LockBitmapBits(pBMObj)
ExAcquireFastMutex((pBMObj)->BitsLock)
-#define BITMAPOBJ_UnlockBitmapBits(pBMObj)
ExReleaseFastMutex((pBMObj)->BitsLock)
+#define BITMAPOBJ_LockBitmapBits(pBMObj)
ExEnterCriticalRegionAndAcquireFastMutexUnsafe((pBMObj)->BitsLock)
+#define BITMAPOBJ_UnlockBitmapBits(pBMObj)
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((pBMObj)->BitsLock)
void INTERNAL_CALL BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *pBMObj);
INT FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp);
_____
Modified: trunk/reactos/ntoskrnl/cc/ccmutex.c
--- trunk/reactos/ntoskrnl/cc/ccmutex.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/cc/ccmutex.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -26,7 +26,7 @@
InterlockedIncrementUL(&FastMutex->Contention);
while (InterlockedExchange(&FastMutex->Count, 0) == 0)
{
- KeWaitForSingleObject(&FastMutex->Event,
+ KeWaitForSingleObject(&FastMutex->Gate,
Executive,
KernelMode,
FALSE,
@@ -50,7 +50,7 @@
InterlockedExchange(&FastMutex->Count, 1);
if (FastMutex->Contention > 0)
{
- KeSetEvent(&FastMutex->Event, 0, FALSE);
+ KeSetEvent(&FastMutex->Gate, 0, FALSE);
}
}
_____
Modified: trunk/reactos/ntoskrnl/cc/fs.c
--- trunk/reactos/ntoskrnl/cc/fs.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/cc/fs.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -153,7 +153,7 @@
if (FileSizes->AllocationSize.QuadPart <
Bcb->AllocationSize.QuadPart)
{
InitializeListHead(&FreeListHead);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
@@ -186,7 +186,7 @@
Bcb->AllocationSize = FileSizes->AllocationSize;
Bcb->FileSize = FileSizes->FileSize;
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
current_entry = FreeListHead.Flink;
while(current_entry != &FreeListHead)
_____
Modified: trunk/reactos/ntoskrnl/cc/pin.c
--- trunk/reactos/ntoskrnl/cc/pin.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/cc/pin.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -236,7 +236,7 @@
IoStatus->Information = 0;
if (WriteThrough)
{
- CcAcquireBrokenMutex(&iBcb->CacheSegment->Lock);
+
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&iBcb->CacheSegment->Lock
);
if (iBcb->CacheSegment->Dirty)
{
IoStatus->Status =
CcRosFlushCacheSegment(iBcb->CacheSegment);
@@ -245,7 +245,7 @@
{
IoStatus->Status = STATUS_SUCCESS;
}
- CcReleaseBrokenMutex(&iBcb->CacheSegment->Lock);
+
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock
);
}
else
{
_____
Modified: trunk/reactos/ntoskrnl/cc/view.c
--- trunk/reactos/ntoskrnl/cc/view.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/cc/view.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -110,6 +110,23 @@
NTSTATUS
CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg);
+BOOLEAN
+FASTCALL
+CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex)
+{
+ KeEnterCriticalRegion();
+ if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+ {
+ FastMutex->Owner = KeGetCurrentThread();
+ return(TRUE);
+ }
+ else
+ {
+ KeLeaveCriticalRegion();
+ return(FALSE);
+ }
+}
+
/* FUNCTIONS
*****************************************************************/
VOID
@@ -132,7 +149,7 @@
{
DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb );
- CcAcquireBrokenMutex(&ViewLock);
+
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
@@ -145,7 +162,7 @@
current, current->ReferenceCount,
current->Dirty, current->PageOut );
}
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
- CcReleaseBrokenMutex(&ViewLock);
+
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
else
{
@@ -167,14 +184,14 @@
Status = WriteCacheSegment(CacheSegment);
if (NT_SUCCESS(Status))
{
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&CacheSegment->Bcb->BcbLock, &oldIrql);
CacheSegment->Dirty = FALSE;
RemoveEntryList(&CacheSegment->DirtySegmentListEntry);
DirtyPageCount -= CacheSegment->Bcb->CacheSegmentSize /
PAGE_SIZE;
CcRosCacheSegmentDecRefCount ( CacheSegment );
KeReleaseSpinLock(&CacheSegment->Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
return(Status);
}
@@ -195,7 +212,7 @@
(*Count) = 0;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
WriteCount[0] = WriteCount[1];
WriteCount[1] = WriteCount[2];
@@ -235,13 +252,13 @@
ASSERT(current->Dirty);
if (current->ReferenceCount > 1)
{
- CcReleaseBrokenMutex(¤t->Lock);
+
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock);
continue;
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
Status = CcRosFlushCacheSegment(current);
- CcReleaseBrokenMutex(¤t->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock);
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
{
DPRINT1("CC: Failed to flush cache segment.\n");
@@ -251,14 +268,14 @@
(*Count) += PagesPerSegment;
Target -= PagesPerSegment;
}
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
current_entry = DirtySegmentListHead.Flink;
}
if (*Count < NewTarget)
{
WriteCount[1] += (NewTarget - *Count);
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
DPRINT("CcRosFlushDirtyPages() finished\n");
return(STATUS_SUCCESS);
@@ -288,7 +305,7 @@
InitializeListHead(&FreeList);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
current_entry = CacheSegmentLRUListHead.Flink;
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
{
@@ -320,7 +337,7 @@
last = current;
current->PageOut = TRUE;
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE;
i++)
{
PFN_TYPE Page;
@@ -331,7 +348,7 @@
break;
}
}
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(current);
current->PageOut = FALSE;
@@ -342,7 +359,7 @@
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
while (!IsListEmpty(&FreeList))
{
@@ -375,7 +392,7 @@
CacheSeg->Valid = Valid;
CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
if (!WasDirty && CacheSeg->Dirty)
{
InsertTailList(&DirtySegmentListHead,
&CacheSeg->DirtySegmentListEntry);
@@ -399,8 +416,8 @@
CcRosCacheSegmentIncRefCount(CacheSeg);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
@@ -428,7 +445,7 @@
{
CcRosCacheSegmentIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcAcquireBrokenMutex(¤t->Lock);
+
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock);
return(current);
}
current_entry = current_entry->Flink;
@@ -455,10 +472,10 @@
}
if (!CacheSeg->Dirty)
{
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
InsertTailList(&DirtySegmentListHead,
&CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
else
{
@@ -469,7 +486,7 @@
CacheSeg->Dirty = TRUE;
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
@@ -500,10 +517,10 @@
if (!WasDirty && NowDirty)
{
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
InsertTailList(&DirtySegmentListHead,
&CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
@@ -518,7 +535,7 @@
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
@@ -568,8 +585,8 @@
current->DirtySegmentListEntry.Blink = NULL;
current->ReferenceCount = 1;
ExInitializeFastMutex(¤t->Lock);
- CcAcquireBrokenMutex(¤t->Lock);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
*CacheSeg = current;
/* There is window between the call to CcRosLookupCacheSegment
@@ -598,11 +615,11 @@
current );
}
#endif
- CcReleaseBrokenMutex(&(*CacheSeg)->Lock);
- CcReleaseBrokenMutex(&ViewLock);
+
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(*CacheSeg)->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg);
*CacheSeg = current;
- CcAcquireBrokenMutex(¤t->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock);
return STATUS_SUCCESS;
}
if (current->FileOffset < FileOffset)
@@ -634,7 +651,7 @@
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
InsertTailList(&CacheSegmentListHead,
¤t->CacheSegmentListEntry);
InsertTailList(&CacheSegmentLRUListHead,
¤t->CacheSegmentLRUListEntry);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
#ifdef CACHE_BITMAP
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
@@ -907,7 +924,7 @@
DPRINT("CcRosFreeCacheSegment(Bcb 0x%p, CacheSeg 0x%p)\n",
Bcb, CacheSeg);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
RemoveEntryList(&CacheSeg->BcbSegmentListEntry);
RemoveEntryList(&CacheSeg->CacheSegmentListEntry);
@@ -919,7 +936,7 @@
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
Status = CcRosInternalFreeCacheSegment(CacheSeg);
return(Status);
@@ -977,7 +994,7 @@
}
}
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
- CcReleaseBrokenMutex(¤t->Lock);
+
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock);
CcRosCacheSegmentDecRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
}
@@ -1018,11 +1035,11 @@
ASSERT(Bcb);
Bcb->RefCount++;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb->RefCount--;
if (Bcb->RefCount == 0)
{
@@ -1059,7 +1076,7 @@
#endif
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
ObDereferenceObject (Bcb->FileObject);
while (!IsListEmpty(&FreeList))
@@ -1069,7 +1086,7 @@
Status = CcRosInternalFreeCacheSegment(current);
}
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
}
return(STATUS_SUCCESS);
}
@@ -1079,7 +1096,7 @@
CcRosReferenceCache(PFILE_OBJECT FileObject)
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(Bcb);
if (Bcb->RefCount == 0)
@@ -1094,7 +1111,7 @@
ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL);
}
Bcb->RefCount++;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
VOID
@@ -1103,7 +1120,7 @@
{
PBCB Bcb;
DPRINT("CcRosSetRemoveOnClose()\n");
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
if (Bcb)
{
@@ -1113,7 +1130,7 @@
CcRosDeleteFileCache(Bcb->FileObject, Bcb);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
@@ -1122,7 +1139,7 @@
CcRosDereferenceCache(PFILE_OBJECT FileObject)
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(Bcb);
if (Bcb->RefCount > 0)
@@ -1142,7 +1159,7 @@
}
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
NTSTATUS STDCALL
@@ -1154,7 +1171,7 @@
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
{
@@ -1181,7 +1198,7 @@
}
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return(STATUS_SUCCESS);
}
@@ -1192,7 +1209,7 @@
PBCB Bcb;
NTSTATUS Status;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
if (Bcb == NULL)
@@ -1213,7 +1230,7 @@
}
Status = STATUS_SUCCESS;
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return Status;
}
@@ -1232,13 +1249,13 @@
DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p,
CacheSegmentSize %d)\n",
FileObject, Bcb, CacheSegmentSize);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
if (Bcb == NULL)
{
Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList);
if (Bcb == NULL)
{
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return(STATUS_UNSUCCESSFUL);
}
memset(Bcb, 0, sizeof(BCB));
@@ -1269,7 +1286,7 @@
RemoveEntryList(&Bcb->BcbRemoveListEntry);
Bcb->BcbRemoveListEntry.Flink = NULL;
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return(STATUS_SUCCESS);
}
@@ -1324,7 +1341,7 @@
break;
}
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
CcTimeStamp++;
if (CcTimeStamp >= 30)
{
@@ -1340,7 +1357,7 @@
CcRosDeleteFileCache(current->FileObject, current);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
}
_____
Modified: trunk/reactos/ntoskrnl/ex/fmutex.c
--- trunk/reactos/ntoskrnl/ex/fmutex.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/ex/fmutex.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -1,11 +1,9 @@
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
* FILE: ntoskrnl/ex/fmutex.c
* PURPOSE: Implements fast mutexes
- *
- * PROGRAMMERS: David Welch (welch(a)cwcom.net)
+ * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net)
*/
/* INCLUDES
*****************************************************************/
@@ -13,49 +11,194 @@
#include <ntoskrnl.h>
#include <internal/debug.h>
+VOID
+FASTCALL
+KiAcquireFastMutex(IN PFAST_MUTEX FastMutex);
+
/* FUNCTIONS
*****************************************************************/
/*
* @implemented
*/
-VOID FASTCALL
-ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
+VOID
+FASTCALL
+ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
{
- ASSERT(KeGetCurrentThread() == NULL || FastMutex->Owner !=
KeGetCurrentThread());
- ASSERT(KeGetCurrentIrql() == APC_LEVEL ||
- KeGetCurrentThread() == NULL ||
- KeGetCurrentThread()->KernelApcDisable);
+ PKTHREAD Thread = KeGetCurrentThread();
+
+ /* Enter the Critical Region */
+ KeEnterCriticalRegion();
+ ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
+ (Thread == NULL) ||
+ (Thread->CombinedApcDisable != 0) ||
+ (Thread->Teb == NULL) ||
+ (Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
+ ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
+
+ /* Decrease the count */
+ if (InterlockedDecrement(&FastMutex->Count))
+ {
+ /* Someone is still holding it, use slow path */
+ KiAcquireFastMutex(FastMutex);
+ }
+
+ /* Set the owner */
+ FastMutex->Owner = Thread;
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex)
+{
+ ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
+ (KeGetCurrentThread() == NULL) ||
+ (KeGetCurrentThread()->CombinedApcDisable != 0) ||
+ (KeGetCurrentThread()->Teb == NULL) ||
+ (KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
+ ASSERT(FastMutex->Owner == KeGetCurrentThread());
- InterlockedIncrementUL(&FastMutex->Contention);
- while (InterlockedExchange(&FastMutex->Count, 0) == 0)
- {
- KeWaitForSingleObject(&FastMutex->Event,
- Executive,
- KernelMode,
- FALSE,
- NULL);
- }
- InterlockedDecrementUL(&FastMutex->Contention);
- FastMutex->Owner = KeGetCurrentThread();
+ /* Erase the owner */
+ FastMutex->Owner = NULL;
+
+ /* Increase the count */
+ if (InterlockedIncrement(&FastMutex->Count) <= 0)
+ {
+ /* Someone was waiting for it, signal the waiter */
+ KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
+ }
+
+ /* Leave the critical region */
+ KeLeaveCriticalRegion();
}
/*
* @implemented
*/
-VOID FASTCALL
+VOID
+FASTCALL
+ExAcquireFastMutex(PFAST_MUTEX FastMutex)
+{
+ ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
+ KIRQL OldIrql;
+
+ /* Raise IRQL to APC */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /* Decrease the count */
+ if (InterlockedDecrement(&FastMutex->Count))
+ {
+ /* Someone is still holding it, use slow path */
+ KiAcquireFastMutex(FastMutex);
+ }
+
+ /* Set the owner and IRQL */
+ FastMutex->Owner = KeGetCurrentThread();
+ FastMutex->OldIrql = OldIrql;
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExReleaseFastMutex (PFAST_MUTEX FastMutex)
+{
+ ASSERT_IRQL(APC_LEVEL);
+
+ /* Erase the owner */
+ FastMutex->Owner = NULL;
+
+ /* Increase the count */
+ if (InterlockedIncrement(&FastMutex->Count) <= 0)
+ {
+ /* Someone was waiting for it, signal the waiter */
+ KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
+ }
+
+ /* Lower IRQL back */
+ KfLowerIrql(FastMutex->OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
+{
+ PKTHREAD Thread = KeGetCurrentThread();
+ ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
+ (Thread == NULL) ||
+ (Thread->CombinedApcDisable != 0) ||
+ (Thread->Teb == NULL) ||
+ (Thread->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
+ ASSERT((Thread == NULL) || (FastMutex->Owner != Thread));
+
+ /* Decrease the count */
+ if (InterlockedDecrement(&FastMutex->Count))
+ {
+ /* Someone is still holding it, use slow path */
+ KiAcquireFastMutex(FastMutex);
+ }
+
+ /* Set the owner */
+ FastMutex->Owner = Thread;
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
ExReleaseFastMutexUnsafe(PFAST_MUTEX FastMutex)
{
- ASSERT(KeGetCurrentThread() == NULL || FastMutex->Owner ==
KeGetCurrentThread());
- ASSERT(KeGetCurrentIrql() == APC_LEVEL ||
- KeGetCurrentThread() == NULL ||
- KeGetCurrentThread()->KernelApcDisable);
+ ASSERT((KeGetCurrentIrql() == APC_LEVEL) ||
+ (KeGetCurrentThread() == NULL) ||
+ (KeGetCurrentThread()->CombinedApcDisable != 0) ||
+ (KeGetCurrentThread()->Teb == NULL) ||
+ (KeGetCurrentThread()->Teb >= (PTEB)MM_SYSTEM_RANGE_START));
+ ASSERT(FastMutex->Owner == KeGetCurrentThread());
- FastMutex->Owner = NULL;
- InterlockedExchange(&FastMutex->Count, 1);
- if (FastMutex->Contention > 0)
+ /* Erase the owner */
+ FastMutex->Owner = NULL;
+
+ /* Increase the count */
+ if (InterlockedIncrement(&FastMutex->Count) <= 0)
{
- KeSetEvent(&FastMutex->Event, 0, FALSE);
+ /* Someone was waiting for it, signal the waiter */
+ KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
}
}
+/*
+ * @implemented
+ */
+BOOLEAN
+FASTCALL
+ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
+{
+ ASSERT_IRQL_LESS_OR_EQUAL(APC_LEVEL);
+ KIRQL OldIrql;
+
+ /* Raise to APC_LEVEL */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+
+ /* Check if we can quickly acquire it */
+ if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1)
+ {
+ /* We have, set us as owners */
+ FastMutex->Owner = KeGetCurrentThread();
+ return TRUE;
+ }
+ else
+ {
+ /* Acquire attempt failed */
+ KfLowerIrql(OldIrql);
+ return FALSE;
+ }
+}
+
/* EOF */
_____
Modified: trunk/reactos/ntoskrnl/include/internal/cc.h
--- trunk/reactos/ntoskrnl/include/internal/cc.h 2005-11-19
21:07:25 UTC (rev 19351)
+++ trunk/reactos/ntoskrnl/include/internal/cc.h 2005-11-19
22:13:35 UTC (rev 19352)
@@ -1,18 +1,6 @@
#ifndef __INCLUDE_INTERNAL_CC_H
#define __INCLUDE_INTERNAL_CC_H
-VOID
-FASTCALL
-CcAcquireBrokenMutex(PFAST_MUTEX FastMutex);
-
-VOID
-FASTCALL
-CcReleaseBrokenMutex(PFAST_MUTEX FastMutex);
-
-BOOLEAN
-FASTCALL
-CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex);
-
typedef struct _BCB
{
LIST_ENTRY BcbSegmentListHead;
_____
Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c 2005-11-19 21:07:25 UTC (rev
19351)
+++ trunk/reactos/ntoskrnl/ke/wait.c 2005-11-19 22:13:35 UTC (rev
19352)
@@ -1,11 +1,10 @@
/*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS project
+ * PROJECT: ReactOS Kernel
* FILE: ntoskrnl/ke/wait.c
[truncated at 1000 lines; 539 more skipped]