- 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@cwcom.net)
- *                  Eric Kohl (ekohl@rz-online.de)
- * UPDATE HISTORY:
- *                  Created 09/06/2000
+ * PURPOSE:         Deprecated HAL Fast Mutex
+ * PROGRAMMERS:     Alex Ionescu (alex@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@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(&current->Lock);
+	  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->Lock);
 	  continue;
 	}
-      CcReleaseBrokenMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
       PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
       Status = CcRosFlushCacheSegment(current);
-      CcReleaseBrokenMutex(&current->Lock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->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(&current->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(&current->Bcb->BcbLock, &oldIrql);
              CcRosCacheSegmentDecRefCount(current);
              current->PageOut = FALSE;
@@ -342,7 +359,7 @@
 	 KeReleaseSpinLock(&current->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(&current->Lock);
+          ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->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(&current->Lock);
-  CcAcquireBrokenMutex(&current->Lock);
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->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(&current->Lock);
+        ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
 	return STATUS_SUCCESS;
      }
      if (current->FileOffset < FileOffset)
@@ -634,7 +651,7 @@
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
   InsertTailList(&CacheSegmentListHead, &current->CacheSegmentListEntry);
   InsertTailList(&CacheSegmentLRUListHead, &current->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(&current->Lock);
+	    ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->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@cwcom.net)
+ * PROGRAMMERS:     Alex Ionescu (alex@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]