- Reimplement Fast Mutex implementation in HAL/NT to be compatible with the real implementation. (Fast Mutex needs to raise IRQL).

- Implement ExEnterCriticalRegionAndAcquireFastMutexUnsafe and ExReleaseFastMutexUnsafeAndLeaveCriticalRegion.
- Make win32k use those two new functions so that it can continue running at PASSIVE_LEVEL.
- Remove CcBrokenMutex and use the new APIs instead.
- Implement and export ntoskrnl version of Fast Mutex
- Update headers for new fast-mutex definition and API exports.
- Fix RemoveEntryList in NDK.
- Add exfuncs.h to NDK.
- Fix path in mmtypes.h in NDK to be compatible to how it shoudl be included.

svn path=/trunk/; revision=19352
This commit is contained in:
Alex Ionescu 2005-11-19 22:13:35 +00:00
parent e89ef63b04
commit b8f8ea844f
24 changed files with 474 additions and 239 deletions

View 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 *****************************************************************/
@ -16,39 +20,77 @@
#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();
}
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;
}
}

View 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

View file

@ -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

View 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 */

View file

@ -175,7 +175,7 @@ RemoveEntryList(
OldBlink = Entry->Blink;
OldFlink->Blink = OldBlink;
OldBlink->Flink = OldFlink;
return (OldFlink == OldBlink);
return (BOOLEAN)(OldFlink == OldBlink);
}
static __inline

View 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);

View file

@ -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);
}
}

View 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)

View 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
{

View 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);
}
}

View 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 *****************************************************************/
@ -13,48 +11,193 @@
#include <ntoskrnl.h>
#include <internal/debug.h>
VOID
FASTCALL
KiAcquireFastMutex(IN PFAST_MUTEX FastMutex);
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
VOID FASTCALL
ExAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
VOID
FASTCALL
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(PFAST_MUTEX FastMutex)
{
ASSERT(KeGetCurrentThread() == NULL || FastMutex->Owner != KeGetCurrentThread());
ASSERT(KeGetCurrentIrql() == APC_LEVEL ||
KeGetCurrentThread() == NULL ||
KeGetCurrentThread()->KernelApcDisable);
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;
}
}

View 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;

View 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

View 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

View 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>

View file

@ -166,7 +166,7 @@ EngUnlockDriverObj ( IN HDRVOBJ hdo )
{
PDRIVERGDI DrvObjInt = ObjToGDI((PDRIVEROBJ)hdo, DRIVER);
ExReleaseFastMutex(&DrvObjInt->Lock);
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&DrvObjInt->Lock);
return TRUE;
}

View 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,

View 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 */

View 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;
}

View 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);

View file

@ -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);
}

View 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)
{

View file

@ -47,10 +47,10 @@ static ULONG HintIndex = 0;
#define IntLockWindowlessTimerBitmap() \
ExAcquireFastMutex(&Mutex)
ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&Mutex)
#define IntUnlockWindowlessTimerBitmap() \
ExReleaseFastMutex(&Mutex)
ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&Mutex)
/* FUNCTIONS *****************************************************************/

View 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);
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