- Reimplement Fast Mutex implementation in HAL/NT to be compatible with the real...
authorAlex Ionescu <aionescu@gmail.com>
Sat, 19 Nov 2005 22:13:35 +0000 (22:13 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sat, 19 Nov 2005 22:13:35 +0000 (22:13 +0000)
- 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.

svn path=/trunk/; revision=19352

24 files changed:
reactos/hal/halx86/generic/fmutex.c
reactos/include/ndk/arch/mmtypes.h
reactos/include/ndk/exfuncs.h [new file with mode: 0644]
reactos/include/ndk/ntndk.h
reactos/include/ndk/rtltypes.h
reactos/include/win32k/bitmaps.h
reactos/ntoskrnl/cc/ccmutex.c
reactos/ntoskrnl/cc/fs.c
reactos/ntoskrnl/cc/pin.c
reactos/ntoskrnl/cc/view.c
reactos/ntoskrnl/ex/fmutex.c
reactos/ntoskrnl/include/internal/cc.h
reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.xml
reactos/subsys/win32k/eng/driverobj.c
reactos/subsys/win32k/include/inteng.h
reactos/subsys/win32k/include/text.h
reactos/subsys/win32k/ntuser/guicheck.c
reactos/subsys/win32k/ntuser/monitor.c
reactos/subsys/win32k/ntuser/ntuser.c
reactos/subsys/win32k/ntuser/ssec.c
reactos/subsys/win32k/ntuser/timer.c
reactos/w32api/include/ddk/winddk.h

index ccfdcfd..faf71a8 100644 (file)
@@ -1,13 +1,17 @@
-/* $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 *****************************************************************/
 #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);
 
-VOID FASTCALL
-ExReleaseFastMutex (PFAST_MUTEX        FastMutex)
-{
-  ExReleaseFastMutexUnsafe(FastMutex);
-  KeLeaveCriticalRegion();
+    /* 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;
+
+    /* Increase the count */
+    if (InterlockedIncrement(&FastMutex->Count) <= 0)
+    {
+        /* Someone was waiting for it, signal the waiter */
+        KeSetEventBoostPriority(&FastMutex->Gate, IO_NO_INCREMENT);
+    }
 
-BOOLEAN FASTCALL
-ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex)
+    /* Lower IRQL back */
+    KfLowerIrql(FastMutex->OldIrql);
+}
+
+BOOLEAN
+FASTCALL
+ExTryToAcquireFastMutex(PFAST_MUTEX FastMutex)
 {
-  KeEnterCriticalRegion();
-  if (InterlockedExchange(&FastMutex->Count, 0) == 1)
+    KIRQL OldIrql;
+
+    /* 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;
     }
 }
 
index ea8dc74..5eb7bba 100644 (file)
@@ -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
diff --git a/reactos/include/ndk/exfuncs.h b/reactos/include/ndk/exfuncs.h
new file mode 100644 (file)
index 0000000..7aa4371
--- /dev/null
@@ -0,0 +1,26 @@
+/*\r
+ * PROJECT:         ReactOS Native Headers\r
+ * FILE:            include/ndk/exfuncs.h\r
+ * PURPOSE:         Prototypes for exported Executive Functions not defined in DDK/IFS\r
+ * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)\r
+ * UPDATE HISTORY:\r
+ *                  Created 06/10/04\r
+ */\r
+#ifndef _EXFUNCS_H\r
+#define _EXFUNCS_H\r
+\r
+/* DEPENDENCIES **************************************************************/\r
+\r
+/* FUNCTION TYPES ************************************************************/\r
+\r
+/* PROTOTYPES ****************************************************************/\r
+\r
+VOID\r
+FASTCALL\r
+ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex);\r
+\r
+VOID\r
+FASTCALL\r
+ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(PFAST_MUTEX FastMutex);\r
+\r
+#endif\r
index a1cfea7..4439bfe 100644 (file)
@@ -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 */
index d0f0808..6dbf2af 100644 (file)
@@ -175,7 +175,7 @@ RemoveEntryList(
     OldBlink = Entry->Blink;
     OldFlink->Blink = OldBlink;
     OldBlink->Flink = OldFlink;
-    return (OldFlink == OldBlink);
+    return (BOOLEAN)(OldFlink == OldBlink);
 }
 
 static __inline
index a689d8a..a0d9e89 100644 (file)
@@ -1,4 +1,3 @@
-
 #ifndef __WIN32K_BITMAPS_H
 #define __WIN32K_BITMAPS_H
 
@@ -38,8 +37,8 @@ typedef struct _BITMAPOBJ
 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);
index 73d640b..baea7e0 100644 (file)
@@ -26,7 +26,7 @@ CcAcquireBrokenMutexUnsafe(PFAST_MUTEX FastMutex)
     InterlockedIncrementUL(&FastMutex->Contention);\r
     while (InterlockedExchange(&FastMutex->Count, 0) == 0)\r
     {\r
-        KeWaitForSingleObject(&FastMutex->Event,\r
+        KeWaitForSingleObject(&FastMutex->Gate,\r
                               Executive,\r
                               KernelMode,\r
                               FALSE,\r
@@ -50,7 +50,7 @@ CcReleaseBrokenMutexUnsafe(PFAST_MUTEX FastMutex)
     InterlockedExchange(&FastMutex->Count, 1);\r
     if (FastMutex->Contention > 0)\r
     {\r
-        KeSetEvent(&FastMutex->Event, 0, FALSE);\r
+        KeSetEvent(&FastMutex->Gate, 0, FALSE);\r
     }\r
 }\r
 \r
index 27b87e5..be97a98 100644 (file)
@@ -153,7 +153,7 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject,
   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 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject,
      Bcb->AllocationSize = FileSizes->AllocationSize;
      Bcb->FileSize = FileSizes->FileSize;
      KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-     CcReleaseBrokenMutex(&ViewLock);
+     ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
      current_entry = FreeListHead.Flink;
      while(current_entry != &FreeListHead)
index 8002434..b845c6c 100644 (file)
@@ -236,7 +236,7 @@ CcUnpinRepinnedBcb (
       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 @@ CcUnpinRepinnedBcb (
             {
               IoStatus->Status = STATUS_SUCCESS;
             }
-          CcReleaseBrokenMutex(&iBcb->CacheSegment->Lock);
+          ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock);
         }
       else
         {
index 8b7fe67..ba99ae3 100644 (file)
@@ -110,6 +110,23 @@ static void CcRosCacheSegmentDecRefCount_ ( PCACHE_SEGMENT cs, const char* file,
 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 @@ CcRosTraceCacheMap (
        {
                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 @@ CcRosTraceCacheMap (
                                current, current->ReferenceCount, current->Dirty, current->PageOut );
                }
                KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
-               CcReleaseBrokenMutex(&ViewLock);
+               ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
        }
        else
        {
@@ -167,14 +184,14 @@ CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment)
   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 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
 
   (*Count) = 0;
 
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   WriteCount[0] = WriteCount[1];
   WriteCount[1] = WriteCount[2];
@@ -235,13 +252,13 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
       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 @@ CcRosFlushDirtyPages(ULONG Target, PULONG Count)
          (*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 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
 
   InitializeListHead(&FreeList);
 
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   current_entry = CacheSegmentLRUListHead.Flink;
   while (current_entry != &CacheSegmentLRUListHead && Target > 0)
     {
@@ -320,7 +337,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
             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 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
                     break;
                   }
               }
-             CcAcquireBrokenMutex(&ViewLock);
+             ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
              KeAcquireSpinLock(&current->Bcb->BcbLock, &oldIrql);
              CcRosCacheSegmentDecRefCount(current);
              current->PageOut = FALSE;
@@ -342,7 +359,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
         KeReleaseSpinLock(&current->Bcb->BcbLock, oldIrql);
       }
   }
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   while (!IsListEmpty(&FreeList))
   {
@@ -375,7 +392,7 @@ CcRosReleaseCacheSegment(PBCB Bcb,
   CacheSeg->Valid = Valid;
   CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
 
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   if (!WasDirty && CacheSeg->Dirty)
     {
       InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
@@ -399,8 +416,8 @@ CcRosReleaseCacheSegment(PBCB Bcb,
       CcRosCacheSegmentIncRefCount(CacheSeg);
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-  CcReleaseBrokenMutex(&ViewLock);
-  CcReleaseBrokenMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
 
   return(STATUS_SUCCESS);
 }
@@ -428,7 +445,7 @@ CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
        {
       CcRosCacheSegmentIncRefCount(current);
          KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-          CcAcquireBrokenMutex(&current->Lock);
+          ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&current->Lock);
          return(current);
        }
       current_entry = current_entry->Flink;
@@ -455,10 +472,10 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
     }
   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 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset)
 
 
   CacheSeg->Dirty = TRUE;
-  CcReleaseBrokenMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
 
   return(STATUS_SUCCESS);
 }
@@ -500,10 +517,10 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
 
   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 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty)
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
 
-  CcReleaseBrokenMutex(&CacheSeg->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
   return(STATUS_SUCCESS);
 }
 
@@ -568,8 +585,8 @@ CcRosCreateCacheSegment(PBCB Bcb,
   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 @@ CcRosCreateCacheSegment(PBCB Bcb,
                        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 @@ CcRosCreateCacheSegment(PBCB Bcb,
   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 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
   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 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg)
 
   }
   KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
   Status = CcRosInternalFreeCacheSegment(CacheSeg);
   return(Status);
@@ -977,7 +994,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers,
               }
            }
             KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
-           CcReleaseBrokenMutex(&current->Lock);
+           ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&current->Lock);
             CcRosCacheSegmentDecRefCount(current);
            KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
         }
@@ -1018,11 +1035,11 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
    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 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
 #endif
       KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
 
-      CcReleaseBrokenMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
       ObDereferenceObject (Bcb->FileObject);
 
       while (!IsListEmpty(&FreeList))
@@ -1069,7 +1086,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
          Status = CcRosInternalFreeCacheSegment(current);
       }
       ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
-      CcAcquireBrokenMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
    }
    return(STATUS_SUCCESS);
 }
@@ -1079,7 +1096,7 @@ NTAPI
 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 @@ CcRosReferenceCache(PFILE_OBJECT FileObject)
      ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL);
   }
   Bcb->RefCount++;
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
 VOID
@@ -1103,7 +1120,7 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
 {
   PBCB Bcb;
   DPRINT("CcRosSetRemoveOnClose()\n");
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
   Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
   if (Bcb)
   {
@@ -1113,7 +1130,7 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer)
       CcRosDeleteFileCache(Bcb->FileObject, Bcb);
     }
   }
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
 
@@ -1122,7 +1139,7 @@ NTAPI
 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 @@ CcRosDereferenceCache(PFILE_OBJECT FileObject)
        }
     }
   }
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 }
 
 NTSTATUS STDCALL
@@ -1154,7 +1171,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
 {
   PBCB Bcb;
 
-  CcAcquireBrokenMutex(&ViewLock);
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
   if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
   {
@@ -1181,7 +1198,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
       }
     }
   }
-  CcReleaseBrokenMutex(&ViewLock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
   return(STATUS_SUCCESS);
 }
 
@@ -1192,7 +1209,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
    PBCB Bcb;
    NTSTATUS Status;
 
-   CcAcquireBrokenMutex(&ViewLock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
 
    Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
    if (Bcb == NULL)
@@ -1213,7 +1230,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
       }
       Status = STATUS_SUCCESS;
    }
-   CcReleaseBrokenMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    return Status;
 }
@@ -1232,13 +1249,13 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject,
    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 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject,
       RemoveEntryList(&Bcb->BcbRemoveListEntry);
       Bcb->BcbRemoveListEntry.Flink = NULL;
    }
-   CcReleaseBrokenMutex(&ViewLock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
 
    return(STATUS_SUCCESS);
 }
@@ -1324,7 +1341,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
          break;
       }
 
-      CcAcquireBrokenMutex(&ViewLock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
       CcTimeStamp++;
       if (CcTimeStamp >= 30)
       {
@@ -1340,7 +1357,7 @@ CmLazyCloseThreadMain(PVOID Ignored)
             CcRosDeleteFileCache(current->FileObject, current);
         }
       }
-      CcReleaseBrokenMutex(&ViewLock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
    }
 }
 
index 7e42fdd..c29f7ce 100644 (file)
@@ -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 *****************************************************************/
 #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)
+{
+    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(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());
   
-  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
+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
+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)
+    {
+        /* 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
     {
-      KeSetEvent(&FastMutex->Event, 0, FALSE);
+        /* Acquire attempt failed */
+        KfLowerIrql(OldIrql);
+        return FALSE;
     }
 }
 
index 4f42b8b..1c2d0f0 100644 (file)
@@ -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;
index 358a5e0..da4e15a 100644 (file)
@@ -1,11 +1,10 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS project
+ * PROJECT:         ReactOS Kernel
  * FILE:            ntoskrnl/ke/wait.c
- * PURPOSE:         Manages non-busy waiting
- *
- * PROGRAMMERS:     Alex Ionescu - Fixes and optimization.
- *                  Gunnar Dalsnes - Implementation
+ * PURPOSE:         Manages dispatch level wait-related code
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Gunnar Dalsnes
  */
 
 /* INCLUDES ******************************************************************/
@@ -756,6 +755,21 @@ KiAbortWaitThread(PKTHREAD Thread,
     KiUnblockThread(Thread, &WaitStatus, 0);
 }
 
+VOID
+FASTCALL
+KiAcquireFastMutex(IN PFAST_MUTEX FastMutex)
+{
+    /* Increase contention count */
+    FastMutex->Contention++;
+
+    /* Wait for the event */
+    KeWaitForSingleObject(&FastMutex->Gate,
+                          WrMutex,
+                          WaitAny,
+                          FALSE,
+                          NULL);
+}
+
 BOOLEAN
 inline
 FASTCALL
index 4764bb6..35da255 100644 (file)
@@ -63,6 +63,7 @@ DbgPrintEx
 DbgPrintReturnControlC
 DbgQueryDebugFilterState@8
 DbgSetDebugFilterState@12
+@ExiAcquireFastMutex@4=@ExAcquireFastMutex@4
 @ExAcquireFastMutexUnsafe@4
 ExAcquireResourceExclusive@8
 ExAcquireResourceExclusiveLite@8
@@ -86,6 +87,7 @@ ExDeleteResourceLite@4
 ExDesktopObjectType DATA
 ExDisableResourceBoostLite@4
 ExEnumHandleTable@16
+@ExEnterCriticalRegionAndAcquireFastMutexUnsafe@4
 ExEventObjectType DATA
 ExExtendZone@12
 ExFreePool@4
@@ -133,7 +135,9 @@ ExRaiseStatus@4=RtlRaiseStatus@4
 ExRegisterCallback@12
 ExReinitializeResourceLite@4
 @ExReInitializeRundownProtection@4
+@ExiReleaseFastMutex@4=@ExReleaseFastMutex@4
 @ExReleaseFastMutexUnsafe@4
+@ExReleaseFastMutexUnsafeAndLeaveCriticalRegion@4
 ExReleaseResourceForThread@8
 ExReleaseResourceForThreadLite@8
 @ExReleaseResourceLite@4
index d8e20ec..50e9b1d 100644 (file)
@@ -73,7 +73,6 @@
        </directory>
        <directory name="cc">
                <file>cacheman.c</file>
-               <file>ccmutex.c</file>
                <file>copy.c</file>
                <file>fs.c</file>
                <file>mdl.c</file>
index e8916e9..59887c7 100644 (file)
@@ -166,7 +166,7 @@ EngUnlockDriverObj ( IN HDRVOBJ hdo )
 {
   PDRIVERGDI DrvObjInt = ObjToGDI((PDRIVEROBJ)hdo, DRIVER);
 
-  ExReleaseFastMutex(&DrvObjInt->Lock);
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&DrvObjInt->Lock);
   return TRUE;
 }
 
index f866870..1c1a17d 100644 (file)
@@ -35,10 +35,10 @@ typedef struct tagSPAN
 /* Definitions of IntEngXxx functions */
 
 #define IntEngLockProcessDriverObjs(W32Process) \
-  ExAcquireFastMutex(&(W32Process)->DriverObjListLock)
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&(W32Process)->DriverObjListLock)
 
 #define IntEngUnLockProcessDriverObjs(W32Process) \
-  ExReleaseFastMutex(&(W32Process)->DriverObjListLock)
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(W32Process)->DriverObjListLock)
 
 VOID FASTCALL
 IntEngCleanupDriverObjs(struct _EPROCESS *Process,
index 2dca5b2..1072e64 100644 (file)
@@ -8,21 +8,21 @@ VOID FASTCALL IntEnableFontRendering(BOOL Enable);
 INT FASTCALL FontGetObject(PTEXTOBJ TextObj, INT Count, PVOID Buffer);
 
 #define IntLockProcessPrivateFonts(W32Process) \
-  ExAcquireFastMutex(&W32Process->PrivateFontListLock)
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&W32Process->PrivateFontListLock)
 
 #define IntUnLockProcessPrivateFonts(W32Process) \
-  ExReleaseFastMutex(&W32Process->PrivateFontListLock)
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&W32Process->PrivateFontListLock)
 
 #define IntLockGlobalFonts \
-  ExAcquireFastMutex(&FontListLock)
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&FontListLock)
 
 #define IntUnLockGlobalFonts \
-  ExReleaseFastMutex(&FontListLock)
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&FontListLock)
 
 #define IntLockFreeType \
-  ExAcquireFastMutex(&FreeTypeLock)
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&FreeTypeLock)
 
 #define IntUnLockFreeType \
-  ExReleaseFastMutex(&FreeTypeLock)
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&FreeTypeLock)
 
 #endif /* _WIN32K_TEXT_H */
index c80b822..60a0c46 100644 (file)
@@ -41,7 +41,6 @@
 /* GLOBALS *******************************************************************/
 
 static LONG NrGuiAppsRunning = 0;
-static FAST_MUTEX GuiSwitchLock;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -53,9 +52,7 @@ co_AddGuiApp(PW32PROCESS W32Data)
    {
       BOOL Initialized;
 
-      ExAcquireFastMutex(&GuiSwitchLock);
       Initialized = co_IntInitializeDesktopGraphics();
-      ExReleaseFastMutex(&GuiSwitchLock);
 
       if (!Initialized)
       {
@@ -73,9 +70,7 @@ RemoveGuiApp(PW32PROCESS W32Data)
    W32Data->Flags &= ~W32PF_CREATEDWINORDC;
    if (InterlockedDecrement(&NrGuiAppsRunning) == 0)
    {
-      ExAcquireFastMutex(&GuiSwitchLock);
       IntEndDesktopGraphics();
-      ExReleaseFastMutex(&GuiSwitchLock);
    }
 }
 
@@ -139,7 +134,6 @@ NtUserManualGuiCheck(LONG Check)
 NTSTATUS FASTCALL
 InitGuiCheckImpl (VOID)
 {
-   ExInitializeFastMutex(&GuiSwitchLock);
    return STATUS_SUCCESS;
 }
 
index 10f9828..212c3b7 100644 (file)
@@ -236,9 +236,9 @@ IntDetachMonitor(IN GDIDEVICE *pGdiDevice)
    {
       PMONITOR_OBJECT NewPrimaryMonitor = (Monitor->Prev != NULL) ? (Monitor->Prev) : (Monitor->Next);
 
-      ExAcquireFastMutex(&NewPrimaryMonitor->Lock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&NewPrimaryMonitor->Lock);
       NewPrimaryMonitor->IsPrimary = TRUE;
-      ExReleaseFastMutex(&NewPrimaryMonitor->Lock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&NewPrimaryMonitor->Lock);
    }
 
    if (gMonitorList == Monitor)
@@ -330,12 +330,12 @@ IntGetMonitorsFromRect(OPTIONAL IN LPCRECT pRect,
    {
       RECT MonitorRect, IntersectionRect;
 
-      ExAcquireFastMutex(&Monitor->Lock);
+      ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Monitor->Lock);
       MonitorRect.left = 0; /* FIXME: get origin */
       MonitorRect.top = 0; /* FIXME: get origin */
       MonitorRect.right = MonitorRect.left + Monitor->GdiDevice->GDIInfo.ulHorzRes;
       MonitorRect.bottom = MonitorRect.top + Monitor->GdiDevice->GDIInfo.ulVertRes;
-      ExReleaseFastMutex(&Monitor->Lock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Monitor->Lock);
 
       DPRINT("MonitorRect: left = %d, top = %d, right = %d, bottom = %d\n",
              MonitorRect.left, MonitorRect.top, MonitorRect.right, MonitorRect.bottom);
index 0417568..b125c6f 100644 (file)
@@ -91,7 +91,7 @@ VOID FASTCALL UUserEnterShared(VOID)
    //DPRINT("%x\n",__builtin_return_address(0));\r
    //   KeEnterCriticalRegion();\r
    //   ExAcquireResourceSharedLite(&UserLock, TRUE);\r
-   ExAcquireFastMutex(&UserLock);\r
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&UserLock);\r
 }\r
 \r
 VOID FASTCALL UUserEnterExclusive(VOID)\r
@@ -101,7 +101,7 @@ VOID FASTCALL UUserEnterExclusive(VOID)
    //DPRINT("%x\n",__builtin_return_address(0));\r
    //   KeEnterCriticalRegion();\r
    //   ExAcquireResourceExclusiveLite(&UserLock, TRUE);\r
-   ExAcquireFastMutex(&UserLock);\r
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&UserLock);\r
 }\r
 \r
 VOID FASTCALL UUserLeave(VOID)\r
@@ -111,5 +111,5 @@ VOID FASTCALL UUserLeave(VOID)
    //DPRINT("%x\n",__builtin_return_address(0));\r
    //  ExReleaseResourceLite(&UserLock);\r
    //   KeLeaveCriticalRegion();\r
-   ExReleaseFastMutex(&UserLock);\r
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&UserLock);\r
 }\r
index 8c18e9d..0f4c3a2 100644 (file)
@@ -82,7 +82,7 @@ IntUserFreeSharedSectionPool(IN PSHARED_SECTION_POOL SharedSectionPool)
 
    Array = &SharedSectionPool->SectionsArray;
 
-   ExAcquireFastMutex(&SharedSectionPool->Lock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
    while(SharedSectionPool->SharedSectionCount > 0 && Array != NULL)
    {
       for(SharedSection = Array->SharedSection, LastSharedSection = SharedSection + Array->nEntries;
@@ -114,7 +114,7 @@ IntUserFreeSharedSectionPool(IN PSHARED_SECTION_POOL SharedSectionPool)
    ASSERT(SharedSectionPool->SectionsArray.Next == NULL);
    ASSERT(SharedSectionPool->SharedSectionCount == 0);
 
-   ExReleaseFastMutex(&SharedSectionPool->Lock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
 }
 
 
@@ -135,11 +135,11 @@ IntUserCreateSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
 
    Size = ROUND_UP(*SharedSectionSize, PAGE_SIZE);
 
-   ExAcquireFastMutex(&SharedSectionPool->Lock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
 
    if(Size > SharedSectionPool->PoolFree)
    {
-      ExReleaseFastMutex(&SharedSectionPool->Lock);
+      ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
       DPRINT1("Shared Section Pool limit (0x%x KB) reached, attempted to allocate a 0x%x KB shared section!\n",
               SharedSectionPool->PoolSize / 1024, (*SharedSectionSize) / 1024);
       return STATUS_INSUFFICIENT_RESOURCES;
@@ -187,7 +187,7 @@ IntUserCreateSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
                                        TAG_SSECTPOOL);
       if(NewArray == NULL)
       {
-         ExReleaseFastMutex(&SharedSectionPool->Lock);
+         ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
          DPRINT1("Failed to allocate new array for shared sections!\n");
          return STATUS_INSUFFICIENT_RESOURCES;
       }
@@ -234,7 +234,7 @@ IntUserCreateSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
       }
    }
 
-   ExReleaseFastMutex(&SharedSectionPool->Lock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
 
    return Status;
 }
@@ -253,7 +253,7 @@ InUserDeleteSharedSection(PSHARED_SECTION_POOL SharedSectionPool,
 
    SectionObject = NULL;
 
-   ExAcquireFastMutex(&SharedSectionPool->Lock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
 
    for(Array = &SharedSectionPool->SectionsArray;
          Array != NULL && SectionObject == NULL;
@@ -276,7 +276,7 @@ InUserDeleteSharedSection(PSHARED_SECTION_POOL SharedSectionPool,
       }
    }
 
-   ExReleaseFastMutex(&SharedSectionPool->Lock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
 
    if(SectionObject != NULL)
    {
@@ -312,7 +312,7 @@ IntUserMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
    SectionObject = NULL;
    SharedSection = NULL;
 
-   ExAcquireFastMutex(&SharedSectionPool->Lock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
 
    for(Array = &SharedSectionPool->SectionsArray;
          Array != NULL && SectionObject == NULL;
@@ -360,7 +360,7 @@ IntUserMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
       Status = STATUS_UNSUCCESSFUL;
    }
 
-   ExReleaseFastMutex(&SharedSectionPool->Lock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
 
    return Status;
 }
@@ -381,7 +381,7 @@ IntUserUnMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
 
    SectionObject = NULL;
 
-   ExAcquireFastMutex(&SharedSectionPool->Lock);
+   ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
 
    for(Array = &SharedSectionPool->SectionsArray;
          Array != NULL && SectionObject == NULL;
@@ -399,7 +399,7 @@ IntUserUnMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool,
       }
    }
 
-   ExReleaseFastMutex(&SharedSectionPool->Lock);
+   ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
 
    if(SectionObject != NULL)
    {
index 892648c..2e9d2a4 100644 (file)
@@ -47,10 +47,10 @@ static ULONG          HintIndex = 0;
 
 
 #define IntLockWindowlessTimerBitmap() \
-  ExAcquireFastMutex(&Mutex)
+  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex)
 
 #define IntUnlockWindowlessTimerBitmap() \
-  ExReleaseFastMutex(&Mutex)
+  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex)
 
 /* FUNCTIONS *****************************************************************/
 
index 6dad684..41d6266 100644 (file)
@@ -376,6 +376,11 @@ typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT;
 
 #define THREAD_ALERT (0x0004)
 
+#define FM_LOCK_BIT             (0x1)
+#define FM_LOCK_BIT_V           (0x0)
+#define FM_LOCK_WAITER_WOKEN    (0x2)
+#define FM_LOCK_WAITER_INC      (0x4)
+
 /* Exported object types */
 extern NTOSAPI POBJECT_TYPE ExDesktopObjectType;
 extern NTOSAPI POBJECT_TYPE ExEventObjectType;
@@ -1110,12 +1115,13 @@ typedef struct _KSEMAPHORE {
     LONG Limit;
 } KSEMAPHORE, *PKSEMAPHORE, *RESTRICTED_POINTER PRKSEMAPHORE;
 
-typedef struct _FAST_MUTEX {
-  LONG  Count;
-  struct _KTHREAD  *Owner;
-  ULONG  Contention;
-  KEVENT  Event;
-  ULONG  OldIrql;
+typedef struct _FAST_MUTEX
+{
+    LONG Count;
+    PKTHREAD Owner;
+    ULONG Contention;
+    KEVENT Gate;
+    ULONG OldIrql;
 } FAST_MUTEX, *PFAST_MUTEX;
 
 typedef struct _KGATE
@@ -6137,23 +6143,64 @@ KeTryToAcquireGuardedMutex(
     PKGUARDED_MUTEX GuardedMutex
 );
 
-/** Executive support routines **/
+/* Fast Mutex */
+#define ExInitializeFastMutex(_FastMutex) \
+{ \
+    (_FastMutex)->Count = FM_LOCK_BIT; \
+    (_FastMutex)->Owner = NULL; \
+    (_FastMutex)->Contention = 0; \
+    KeInitializeEvent(&(_FastMutex)->Gate, SynchronizationEvent, FALSE); \
+}
+
+NTOSAPI
+VOID
+FASTCALL
+ExAcquireFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex);
+
+NTOSAPI
+VOID
+FASTCALL
+ExReleaseFastMutexUnsafe(IN OUT PFAST_MUTEX FastMutex);
+
+#if defined(_NTHAL_) && defined(_X86_)
+NTOSAPI
+VOID
+FASTCALL
+ExiAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
+
+NTOSAPI
+VOID
+FASTCALL
+ExiReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex);
+
+NTOSAPI
+BOOLEAN
+FASTCALL
+ExiTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
+
+#define ExAcquireFastMutex(FastMutex)       ExiAcquireFastMutex(FastMutex)
+#define ExReleaseFastMutex(FastMutex)       ExiReleaseFastMutex(FastMutex)
+#define ExTryToAcquireFastMutex(FastMutex)  ExiTryToAcquireFastMutex(FastMutex)
 
-#if defined(_X86_)
-NTHALAPI
 #else
+
 NTOSAPI
-#endif
 VOID
-DDKFASTAPI
-ExAcquireFastMutex(
-  IN PFAST_MUTEX  FastMutex);
+FASTCALL
+ExAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
 
 NTOSAPI
 VOID
-DDKFASTAPI
-ExAcquireFastMutexUnsafe(
-  IN PFAST_MUTEX  FastMutex);
+FASTCALL
+ExReleaseFastMutex(IN OUT PFAST_MUTEX FastMutex);
+
+NTOSAPI
+BOOLEAN
+FASTCALL
+ExTryToAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex);
+#endif
+
+/** Executive support routines **/
 
 NTOSAPI
 BOOLEAN
@@ -6376,19 +6423,6 @@ KeInitializeEvent(
   IN EVENT_TYPE  Type,
   IN BOOLEAN  State);
 
-/*
- * VOID DDKAPI
- * ExInitializeFastMutex(
- *   IN PFAST_MUTEX  FastMutex)
- */
-#define ExInitializeFastMutex(_FastMutex) \
-{ \
-  (_FastMutex)->Count = 1; \
-  (_FastMutex)->Owner = NULL; \
-  (_FastMutex)->Contention = 0; \
-  KeInitializeEvent(&(_FastMutex)->Event, SynchronizationEvent, FALSE); \
-}
-
 NTOSAPI
 VOID
 DDKAPI
@@ -6606,22 +6640,6 @@ DDKAPI
 ExReinitializeResourceLite(
   IN PERESOURCE  Resource);
 
-#if defined(_X86_)
-NTHALAPI
-#else
-NTOSAPI
-#endif
-VOID
-DDKFASTAPI
-ExReleaseFastMutex(
-  IN PFAST_MUTEX  FastMutex);
-
-NTOSAPI
-VOID
-DDKFASTAPI
-ExReleaseFastMutexUnsafe(
-  IN PFAST_MUTEX  FastMutex);
-
 NTOSAPI
 VOID
 DDKAPI
@@ -6656,16 +6674,6 @@ ExSystemTimeToLocalTime(
   IN PLARGE_INTEGER  SystemTime,
   OUT PLARGE_INTEGER  LocalTime);
 
-#ifdef _M_IX86
-NTHALAPI
-#else
-NTOSAPI
-#endif
-BOOLEAN
-DDKFASTAPI
-ExTryToAcquireFastMutex(
-  IN PFAST_MUTEX  FastMutex);
-
 NTOSAPI
 BOOLEAN
 DDKAPI