- 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
-/* $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;
}
}
#define _ARCH_MMTYPES_H
#ifdef _M_IX86
-#include <ndk/i386/mmtypes.h>
+#include "./../i386/mmtypes.h"
#else
#error "Unknown processor"
#endif
--- /dev/null
+/*\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
#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 */
OldBlink = Entry->Blink;
OldFlink->Blink = OldBlink;
OldBlink->Flink = OldFlink;
- return (OldFlink == OldBlink);
+ return (BOOLEAN)(OldFlink == OldBlink);
}
static __inline
-
#ifndef __WIN32K_BITMAPS_H
#define __WIN32K_BITMAPS_H
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);
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
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
if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
{
InitializeListHead(&FreeListHead);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
Bcb->AllocationSize = FileSizes->AllocationSize;
Bcb->FileSize = FileSizes->FileSize;
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
current_entry = FreeListHead.Flink;
while(current_entry != &FreeListHead)
IoStatus->Information = 0;
if (WriteThrough)
{
- CcAcquireBrokenMutex(&iBcb->CacheSegment->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&iBcb->CacheSegment->Lock);
if (iBcb->CacheSegment->Dirty)
{
IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment);
{
IoStatus->Status = STATUS_SUCCESS;
}
- CcReleaseBrokenMutex(&iBcb->CacheSegment->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock);
}
else
{
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
{
DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb );
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(&Bcb->BcbLock, &oldirql);
current_entry = Bcb->BcbSegmentListHead.Flink;
current, current->ReferenceCount, current->Dirty, current->PageOut );
}
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
else
{
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);
}
(*Count) = 0;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
WriteCount[0] = WriteCount[1];
WriteCount[1] = WriteCount[2];
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");
(*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);
InitializeListHead(&FreeList);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
current_entry = CacheSegmentLRUListHead.Flink;
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
{
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;
break;
}
}
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
CcRosCacheSegmentDecRefCount(current);
current->PageOut = FALSE;
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
while (!IsListEmpty(&FreeList))
{
CacheSeg->Valid = Valid;
CacheSeg->Dirty = CacheSeg->Dirty || Dirty;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
if (!WasDirty && CacheSeg->Dirty)
{
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
CcRosCacheSegmentIncRefCount(CacheSeg);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
{
CcRosCacheSegmentIncRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcAcquireBrokenMutex(¤t->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock);
return(current);
}
current_entry = current_entry->Flink;
}
if (!CacheSeg->Dirty)
{
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
else
{
CacheSeg->Dirty = TRUE;
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
if (!WasDirty && NowDirty)
{
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry);
DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&CacheSeg->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock);
return(STATUS_SUCCESS);
}
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
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)
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry);
InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
#ifdef CACHE_BITMAP
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
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);
}
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
Status = CcRosInternalFreeCacheSegment(CacheSeg);
return(Status);
}
}
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
- CcReleaseBrokenMutex(¤t->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock);
CcRosCacheSegmentDecRefCount(current);
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
}
ASSERT(Bcb);
Bcb->RefCount++;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb->RefCount--;
if (Bcb->RefCount == 0)
{
#endif
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
ObDereferenceObject (Bcb->FileObject);
while (!IsListEmpty(&FreeList))
Status = CcRosInternalFreeCacheSegment(current);
}
ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
}
return(STATUS_SUCCESS);
}
CcRosReferenceCache(PFILE_OBJECT FileObject)
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(Bcb);
if (Bcb->RefCount == 0)
ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL);
}
Bcb->RefCount++;
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
VOID
{
PBCB Bcb;
DPRINT("CcRosSetRemoveOnClose()\n");
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)SectionObjectPointer->SharedCacheMap;
if (Bcb)
{
CcRosDeleteFileCache(Bcb->FileObject, Bcb);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
CcRosDereferenceCache(PFILE_OBJECT FileObject)
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(Bcb);
if (Bcb->RefCount > 0)
}
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
NTSTATUS STDCALL
{
PBCB Bcb;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
{
}
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return(STATUS_SUCCESS);
}
PBCB Bcb;
NTSTATUS Status;
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
if (Bcb == NULL)
}
Status = STATUS_SUCCESS;
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return Status;
}
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));
RemoveEntryList(&Bcb->BcbRemoveListEntry);
Bcb->BcbRemoveListEntry.Flink = NULL;
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
return(STATUS_SUCCESS);
}
break;
}
- CcAcquireBrokenMutex(&ViewLock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock);
CcTimeStamp++;
if (CcTimeStamp >= 30)
{
CcRosDeleteFileCache(current->FileObject, current);
}
}
- CcReleaseBrokenMutex(&ViewLock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock);
}
}
-/* $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;
}
}
#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;
/*
* 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 ******************************************************************/
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
DbgPrintReturnControlC
DbgQueryDebugFilterState@8
DbgSetDebugFilterState@12
+@ExiAcquireFastMutex@4=@ExAcquireFastMutex@4
@ExAcquireFastMutexUnsafe@4
ExAcquireResourceExclusive@8
ExAcquireResourceExclusiveLite@8
ExDesktopObjectType DATA
ExDisableResourceBoostLite@4
ExEnumHandleTable@16
+@ExEnterCriticalRegionAndAcquireFastMutexUnsafe@4
ExEventObjectType DATA
ExExtendZone@12
ExFreePool@4
ExRegisterCallback@12
ExReinitializeResourceLite@4
@ExReInitializeRundownProtection@4
+@ExiReleaseFastMutex@4=@ExReleaseFastMutex@4
@ExReleaseFastMutexUnsafe@4
+@ExReleaseFastMutexUnsafeAndLeaveCriticalRegion@4
ExReleaseResourceForThread@8
ExReleaseResourceForThreadLite@8
@ExReleaseResourceLite@4
</directory>
<directory name="cc">
<file>cacheman.c</file>
- <file>ccmutex.c</file>
<file>copy.c</file>
<file>fs.c</file>
<file>mdl.c</file>
{
PDRIVERGDI DrvObjInt = ObjToGDI((PDRIVEROBJ)hdo, DRIVER);
- ExReleaseFastMutex(&DrvObjInt->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&DrvObjInt->Lock);
return TRUE;
}
/* 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,
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 */
/* GLOBALS *******************************************************************/
static LONG NrGuiAppsRunning = 0;
-static FAST_MUTEX GuiSwitchLock;
/* FUNCTIONS *****************************************************************/
{
BOOL Initialized;
- ExAcquireFastMutex(&GuiSwitchLock);
Initialized = co_IntInitializeDesktopGraphics();
- ExReleaseFastMutex(&GuiSwitchLock);
if (!Initialized)
{
W32Data->Flags &= ~W32PF_CREATEDWINORDC;
if (InterlockedDecrement(&NrGuiAppsRunning) == 0)
{
- ExAcquireFastMutex(&GuiSwitchLock);
IntEndDesktopGraphics();
- ExReleaseFastMutex(&GuiSwitchLock);
}
}
NTSTATUS FASTCALL
InitGuiCheckImpl (VOID)
{
- ExInitializeFastMutex(&GuiSwitchLock);
return STATUS_SUCCESS;
}
{
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)
{
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);
//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
//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
//DPRINT("%x\n",__builtin_return_address(0));\r
// ExReleaseResourceLite(&UserLock);\r
// KeLeaveCriticalRegion();\r
- ExReleaseFastMutex(&UserLock);\r
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&UserLock);\r
}\r
Array = &SharedSectionPool->SectionsArray;
- ExAcquireFastMutex(&SharedSectionPool->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
while(SharedSectionPool->SharedSectionCount > 0 && Array != NULL)
{
for(SharedSection = Array->SharedSection, LastSharedSection = SharedSection + Array->nEntries;
ASSERT(SharedSectionPool->SectionsArray.Next == NULL);
ASSERT(SharedSectionPool->SharedSectionCount == 0);
- ExReleaseFastMutex(&SharedSectionPool->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
}
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;
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;
}
}
}
- ExReleaseFastMutex(&SharedSectionPool->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
return Status;
}
SectionObject = NULL;
- ExAcquireFastMutex(&SharedSectionPool->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
for(Array = &SharedSectionPool->SectionsArray;
Array != NULL && SectionObject == NULL;
}
}
- ExReleaseFastMutex(&SharedSectionPool->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
if(SectionObject != NULL)
{
SectionObject = NULL;
SharedSection = NULL;
- ExAcquireFastMutex(&SharedSectionPool->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
for(Array = &SharedSectionPool->SectionsArray;
Array != NULL && SectionObject == NULL;
Status = STATUS_UNSUCCESSFUL;
}
- ExReleaseFastMutex(&SharedSectionPool->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
return Status;
}
SectionObject = NULL;
- ExAcquireFastMutex(&SharedSectionPool->Lock);
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool->Lock);
for(Array = &SharedSectionPool->SectionsArray;
Array != NULL && SectionObject == NULL;
}
}
- ExReleaseFastMutex(&SharedSectionPool->Lock);
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool->Lock);
if(SectionObject != NULL)
{
#define IntLockWindowlessTimerBitmap() \
- ExAcquireFastMutex(&Mutex)
+ ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex)
#define IntUnlockWindowlessTimerBitmap() \
- ExReleaseFastMutex(&Mutex)
+ ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex)
/* FUNCTIONS *****************************************************************/
#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;
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
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
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
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
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