diff --git a/reactos/hal/halx86/generic/fmutex.c b/reactos/hal/halx86/generic/fmutex.c index ccfdcfd904b..faf71a8cfed 100644 --- a/reactos/hal/halx86/generic/fmutex.c +++ b/reactos/hal/halx86/generic/fmutex.c @@ -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 *****************************************************************/ @@ -16,39 +20,77 @@ #define NDEBUG #include +#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(); -} - - -BOOLEAN FASTCALL -ExTryToAcquireFastMutex (PFAST_MUTEX FastMutex) -{ - KeEnterCriticalRegion(); - if (InterlockedExchange(&FastMutex->Count, 0) == 1) + /* Decrease the count */ + if (InterlockedDecrement(&FastMutex->Count)) { - FastMutex->Owner = KeGetCurrentThread(); - return(TRUE); + /* Someone is still holding it, use slow path */ + FastMutex->Contention++; + KeWaitForSingleObject(&FastMutex->Gate, + WrExecutive, + WaitAny, + FALSE, + NULL); } - else + + /* 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) { - KeLeaveCriticalRegion(); - return(FALSE); + /* 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; + + /* 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; } } diff --git a/reactos/include/ndk/arch/mmtypes.h b/reactos/include/ndk/arch/mmtypes.h index ea8dc749a71..5eb7bba77af 100644 --- a/reactos/include/ndk/arch/mmtypes.h +++ b/reactos/include/ndk/arch/mmtypes.h @@ -10,7 +10,7 @@ #define _ARCH_MMTYPES_H #ifdef _M_IX86 -#include +#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 index 00000000000..7aa43719294 --- /dev/null +++ b/reactos/include/ndk/exfuncs.h @@ -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 diff --git a/reactos/include/ndk/ntndk.h b/reactos/include/ndk/ntndk.h index a1cfea70708..4439bfe7ac2 100644 --- a/reactos/include/ndk/ntndk.h +++ b/reactos/include/ndk/ntndk.h @@ -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 */ diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index d0f08087edb..6dbf2afaad4 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -175,7 +175,7 @@ RemoveEntryList( OldBlink = Entry->Blink; OldFlink->Blink = OldBlink; OldBlink->Flink = OldFlink; - return (OldFlink == OldBlink); + return (BOOLEAN)(OldFlink == OldBlink); } static __inline diff --git a/reactos/include/win32k/bitmaps.h b/reactos/include/win32k/bitmaps.h index a689d8a67f7..a0d9e89cb65 100644 --- a/reactos/include/win32k/bitmaps.h +++ b/reactos/include/win32k/bitmaps.h @@ -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); diff --git a/reactos/ntoskrnl/cc/ccmutex.c b/reactos/ntoskrnl/cc/ccmutex.c index 73d640b26ae..baea7e0f38e 100644 --- a/reactos/ntoskrnl/cc/ccmutex.c +++ b/reactos/ntoskrnl/cc/ccmutex.c @@ -26,7 +26,7 @@ CcAcquireBrokenMutexUnsafe(PFAST_MUTEX FastMutex) InterlockedIncrementUL(&FastMutex->Contention); while (InterlockedExchange(&FastMutex->Count, 0) == 0) { - KeWaitForSingleObject(&FastMutex->Event, + KeWaitForSingleObject(&FastMutex->Gate, Executive, KernelMode, FALSE, @@ -50,7 +50,7 @@ CcReleaseBrokenMutexUnsafe(PFAST_MUTEX FastMutex) InterlockedExchange(&FastMutex->Count, 1); if (FastMutex->Contention > 0) { - KeSetEvent(&FastMutex->Event, 0, FALSE); + KeSetEvent(&FastMutex->Gate, 0, FALSE); } } diff --git a/reactos/ntoskrnl/cc/fs.c b/reactos/ntoskrnl/cc/fs.c index 27b87e58ade..be97a98b313 100644 --- a/reactos/ntoskrnl/cc/fs.c +++ b/reactos/ntoskrnl/cc/fs.c @@ -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) diff --git a/reactos/ntoskrnl/cc/pin.c b/reactos/ntoskrnl/cc/pin.c index 8002434d961..b845c6c0ac5 100644 --- a/reactos/ntoskrnl/cc/pin.c +++ b/reactos/ntoskrnl/cc/pin.c @@ -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 { diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 8b7fe676657..ba99ae33e52 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -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(¤t->Lock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock); continue; } - CcReleaseBrokenMutex(&ViewLock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE; Status = CcRosFlushCacheSegment(current); - CcReleaseBrokenMutex(¤t->Lock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock); if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) { DPRINT1("CC: Failed to flush cache segment.\n"); @@ -251,14 +268,14 @@ 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(¤t->Bcb->BcbLock, oldIrql); - CcReleaseBrokenMutex(&ViewLock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++) { PFN_TYPE Page; @@ -331,7 +348,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) break; } } - CcAcquireBrokenMutex(&ViewLock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql); CcRosCacheSegmentDecRefCount(current); current->PageOut = FALSE; @@ -342,7 +359,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) KeReleaseSpinLock(¤t->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(¤t->Lock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->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(¤t->Lock); - CcAcquireBrokenMutex(¤t->Lock); - CcAcquireBrokenMutex(&ViewLock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); *CacheSeg = current; /* There is window between the call to CcRosLookupCacheSegment @@ -598,11 +615,11 @@ CcRosCreateCacheSegment(PBCB Bcb, current ); } #endif - CcReleaseBrokenMutex(&(*CacheSeg)->Lock); - CcReleaseBrokenMutex(&ViewLock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(*CacheSeg)->Lock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); *CacheSeg = current; - CcAcquireBrokenMutex(¤t->Lock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock); return STATUS_SUCCESS; } if (current->FileOffset < FileOffset) @@ -634,7 +651,7 @@ CcRosCreateCacheSegment(PBCB Bcb, KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - CcReleaseBrokenMutex(&ViewLock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); #ifdef CACHE_BITMAP KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); @@ -907,7 +924,7 @@ 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(¤t->Lock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->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); } } diff --git a/reactos/ntoskrnl/ex/fmutex.c b/reactos/ntoskrnl/ex/fmutex.c index 7e42fdde908..c29f7cee2b8 100644 --- a/reactos/ntoskrnl/ex/fmutex.c +++ b/reactos/ntoskrnl/ex/fmutex.c @@ -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,48 +11,193 @@ #include #include +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); - - InterlockedIncrementUL(&FastMutex->Contention); - while (InterlockedExchange(&FastMutex->Count, 0) == 0) - { - KeWaitForSingleObject(&FastMutex->Event, - Executive, - KernelMode, - FALSE, - NULL); - } - InterlockedDecrementUL(&FastMutex->Contention); - FastMutex->Owner = KeGetCurrentThread(); + 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 +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()); + + /* 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 +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; } } diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index 4f42b8bb224..1c2d0f0f7b7 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -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; diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 358a5e03704..da4e15a182f 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -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 diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 4764bb69f30..35da2554664 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -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 diff --git a/reactos/ntoskrnl/ntoskrnl.xml b/reactos/ntoskrnl/ntoskrnl.xml index d8e20ec6d02..50e9b1dc5f8 100644 --- a/reactos/ntoskrnl/ntoskrnl.xml +++ b/reactos/ntoskrnl/ntoskrnl.xml @@ -73,7 +73,6 @@ cacheman.c - ccmutex.c copy.c fs.c mdl.c diff --git a/reactos/subsys/win32k/eng/driverobj.c b/reactos/subsys/win32k/eng/driverobj.c index e8916e9c527..59887c7f339 100644 --- a/reactos/subsys/win32k/eng/driverobj.c +++ b/reactos/subsys/win32k/eng/driverobj.c @@ -166,7 +166,7 @@ EngUnlockDriverObj ( IN HDRVOBJ hdo ) { PDRIVERGDI DrvObjInt = ObjToGDI((PDRIVEROBJ)hdo, DRIVER); - ExReleaseFastMutex(&DrvObjInt->Lock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&DrvObjInt->Lock); return TRUE; } diff --git a/reactos/subsys/win32k/include/inteng.h b/reactos/subsys/win32k/include/inteng.h index f8668708836..1c1a17dfda0 100644 --- a/reactos/subsys/win32k/include/inteng.h +++ b/reactos/subsys/win32k/include/inteng.h @@ -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, diff --git a/reactos/subsys/win32k/include/text.h b/reactos/subsys/win32k/include/text.h index 2dca5b27da2..1072e6455d7 100644 --- a/reactos/subsys/win32k/include/text.h +++ b/reactos/subsys/win32k/include/text.h @@ -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 */ diff --git a/reactos/subsys/win32k/ntuser/guicheck.c b/reactos/subsys/win32k/ntuser/guicheck.c index c80b822fd6e..60a0c46a1ff 100644 --- a/reactos/subsys/win32k/ntuser/guicheck.c +++ b/reactos/subsys/win32k/ntuser/guicheck.c @@ -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; } diff --git a/reactos/subsys/win32k/ntuser/monitor.c b/reactos/subsys/win32k/ntuser/monitor.c index 10f9828d4ed..212c3b7e2f4 100644 --- a/reactos/subsys/win32k/ntuser/monitor.c +++ b/reactos/subsys/win32k/ntuser/monitor.c @@ -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); diff --git a/reactos/subsys/win32k/ntuser/ntuser.c b/reactos/subsys/win32k/ntuser/ntuser.c index 0417568d83b..b125c6f0889 100644 --- a/reactos/subsys/win32k/ntuser/ntuser.c +++ b/reactos/subsys/win32k/ntuser/ntuser.c @@ -91,7 +91,7 @@ VOID FASTCALL UUserEnterShared(VOID) //DPRINT("%x\n",__builtin_return_address(0)); // KeEnterCriticalRegion(); // ExAcquireResourceSharedLite(&UserLock, TRUE); - ExAcquireFastMutex(&UserLock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&UserLock); } VOID FASTCALL UUserEnterExclusive(VOID) @@ -101,7 +101,7 @@ VOID FASTCALL UUserEnterExclusive(VOID) //DPRINT("%x\n",__builtin_return_address(0)); // KeEnterCriticalRegion(); // ExAcquireResourceExclusiveLite(&UserLock, TRUE); - ExAcquireFastMutex(&UserLock); + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&UserLock); } VOID FASTCALL UUserLeave(VOID) @@ -111,5 +111,5 @@ VOID FASTCALL UUserLeave(VOID) //DPRINT("%x\n",__builtin_return_address(0)); // ExReleaseResourceLite(&UserLock); // KeLeaveCriticalRegion(); - ExReleaseFastMutex(&UserLock); + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&UserLock); } diff --git a/reactos/subsys/win32k/ntuser/ssec.c b/reactos/subsys/win32k/ntuser/ssec.c index 8c18e9de0ac..0f4c3a265c6 100644 --- a/reactos/subsys/win32k/ntuser/ssec.c +++ b/reactos/subsys/win32k/ntuser/ssec.c @@ -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) { diff --git a/reactos/subsys/win32k/ntuser/timer.c b/reactos/subsys/win32k/ntuser/timer.c index 892648ce1b7..2e9d2a42dd6 100644 --- a/reactos/subsys/win32k/ntuser/timer.c +++ b/reactos/subsys/win32k/ntuser/timer.c @@ -47,10 +47,10 @@ static ULONG HintIndex = 0; #define IntLockWindowlessTimerBitmap() \ - ExAcquireFastMutex(&Mutex) + ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex) #define IntUnlockWindowlessTimerBitmap() \ - ExReleaseFastMutex(&Mutex) + ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex) /* FUNCTIONS *****************************************************************/ diff --git a/reactos/w32api/include/ddk/winddk.h b/reactos/w32api/include/ddk/winddk.h index 6dad684d134..41d626649a6 100644 --- a/reactos/w32api/include/ddk/winddk.h +++ b/reactos/w32api/include/ddk/winddk.h @@ -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); NTOSAPI VOID -DDKFASTAPI -ExAcquireFastMutexUnsafe( - IN PFAST_MUTEX FastMutex); +FASTCALL +ExAcquireFastMutex(IN OUT PFAST_MUTEX FastMutex); + +NTOSAPI +VOID +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