diff --git a/reactos/ntoskrnl/cc/fs.c b/reactos/ntoskrnl/cc/fs.c index 3e9bcd794ce..77d6bc42252 100644 --- a/reactos/ntoskrnl/cc/fs.c +++ b/reactos/ntoskrnl/cc/fs.c @@ -20,7 +20,7 @@ /* GLOBALS *****************************************************************/ -extern FAST_MUTEX ViewLock; +extern KGUARDED_MUTEX ViewLock; extern ULONG DirtyPageCount; NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); @@ -153,7 +153,7 @@ CcSetFileSizes (IN PFILE_OBJECT FileObject, if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart) { InitializeListHead(&FreeListHead); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&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); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); current_entry = FreeListHead.Flink; while(current_entry != &FreeListHead) diff --git a/reactos/ntoskrnl/cc/pin.c b/reactos/ntoskrnl/cc/pin.c index ec1b93b9ceb..d7b70fd5137 100644 --- a/reactos/ntoskrnl/cc/pin.c +++ b/reactos/ntoskrnl/cc/pin.c @@ -236,7 +236,7 @@ CcUnpinRepinnedBcb ( IoStatus->Information = 0; if (WriteThrough) { - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&iBcb->CacheSegment->Lock); + ExAcquirePushLockExclusive(&iBcb->CacheSegment->Lock); if (iBcb->CacheSegment->Dirty) { IoStatus->Status = CcRosFlushCacheSegment(iBcb->CacheSegment); @@ -245,7 +245,7 @@ CcUnpinRepinnedBcb ( { IoStatus->Status = STATUS_SUCCESS; } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&iBcb->CacheSegment->Lock); + ExReleasePushLockExclusive(&iBcb->CacheSegment->Lock); } else { diff --git a/reactos/ntoskrnl/cc/view.c b/reactos/ntoskrnl/cc/view.c index 838a46cec16..b208e7a703a 100644 --- a/reactos/ntoskrnl/cc/view.c +++ b/reactos/ntoskrnl/cc/view.c @@ -56,7 +56,7 @@ static LIST_ENTRY CacheSegmentLRUListHead; static LIST_ENTRY ClosedListHead; ULONG DirtyPageCount=0; -FAST_MUTEX ViewLock; +KGUARDED_MUTEX ViewLock; #ifdef CACHE_BITMAP #define CI_CACHESEG_MAPPING_REGION_SIZE (128*1024*1024) @@ -114,22 +114,6 @@ static void CcRosCacheSegmentDecRefCount_ ( PCACHE_SEGMENT cs, const char* file, NTSTATUS CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg); -BOOLEAN -FASTCALL -CcTryToAcquireBrokenMutex(PFAST_MUTEX FastMutex) -{ - KeEnterCriticalRegion(); - if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) == 1) - { - FastMutex->Owner = KeGetCurrentThread(); - return(TRUE); - } - else - { - KeLeaveCriticalRegion(); - return(FALSE); - } -} /* FUNCTIONS *****************************************************************/ @@ -153,7 +137,7 @@ CcRosTraceCacheMap ( { DPRINT1("Enabling Tracing for CacheMap 0x%p:\n", Bcb ); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&Bcb->BcbLock, &oldirql); current_entry = Bcb->BcbSegmentListHead.Flink; @@ -166,7 +150,7 @@ CcRosTraceCacheMap ( current, current->ReferenceCount, current->Dirty, current->PageOut ); } KeReleaseSpinLock(&Bcb->BcbLock, oldirql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } else { @@ -183,119 +167,130 @@ NTSTATUS NTAPI CcRosFlushCacheSegment(PCACHE_SEGMENT CacheSegment) { - NTSTATUS Status; - KIRQL oldIrql; - Status = WriteCacheSegment(CacheSegment); - if (NT_SUCCESS(Status)) + NTSTATUS Status; + KIRQL oldIrql; + + Status = WriteCacheSegment(CacheSegment); + if (NT_SUCCESS(Status)) { - 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); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeAcquireGuardedMutex(&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); + KeReleaseGuardedMutex(&ViewLock); } - return(Status); + + return(Status); } NTSTATUS NTAPI CcRosFlushDirtyPages(ULONG Target, PULONG Count) { - PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; - ULONG PagesPerSegment; - BOOLEAN Locked; - NTSTATUS Status; - static ULONG WriteCount[4] = {0, 0, 0, 0}; - ULONG NewTarget; - - DPRINT("CcRosFlushDirtyPages(Target %d)\n", Target); - - (*Count) = 0; - - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); - - WriteCount[0] = WriteCount[1]; - WriteCount[1] = WriteCount[2]; - WriteCount[2] = WriteCount[3]; - WriteCount[3] = 0; - - NewTarget = WriteCount[0] + WriteCount[1] + WriteCount[2]; - - if (NewTarget < DirtyPageCount) - { - NewTarget = (DirtyPageCount - NewTarget + 3) / 4; - WriteCount[0] += NewTarget; - WriteCount[1] += NewTarget; - WriteCount[2] += NewTarget; - WriteCount[3] += NewTarget; - } - - NewTarget = WriteCount[0]; - - Target = max(NewTarget, Target); - - current_entry = DirtySegmentListHead.Flink; - if (current_entry == &DirtySegmentListHead) - { - DPRINT("No Dirty pages\n"); - } - while (current_entry != &DirtySegmentListHead && Target > 0) + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + ULONG PagesPerSegment; + BOOLEAN Locked; + NTSTATUS Status; + static ULONG WriteCount[4] = {0, 0, 0, 0}; + ULONG NewTarget; + + DPRINT("CcRosFlushDirtyPages(Target %d)\n", Target); + + (*Count) = 0; + + KeAcquireGuardedMutex(&ViewLock); + + WriteCount[0] = WriteCount[1]; + WriteCount[1] = WriteCount[2]; + WriteCount[2] = WriteCount[3]; + WriteCount[3] = 0; + + NewTarget = WriteCount[0] + WriteCount[1] + WriteCount[2]; + + if (NewTarget < DirtyPageCount) { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - DirtySegmentListEntry); - current_entry = current_entry->Flink; - -// Locked = current->Bcb->Callbacks.AcquireForLazyWrite(current->Bcb->Context, FALSE); - Locked = ExTryToAcquireResourceExclusiveLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); - if (!Locked) - { - continue; - } - Locked = CcTryToAcquireBrokenMutex(¤t->Lock); - if (!Locked) - { -// current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context); - ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); - continue; - } - ASSERT(current->Dirty); - if (current->ReferenceCount > 1) - { - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock); -// current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context); - ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); - continue; - } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); - PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE; - Status = CcRosFlushCacheSegment(current); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock); -// current->Bcb->Callbacks.ReleaseFromLazyWrite(current->Bcb->Context); - ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); - if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) - { - DPRINT1("CC: Failed to flush cache segment.\n"); - } - else - { - (*Count) += PagesPerSegment; - Target -= PagesPerSegment; - } - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); - current_entry = DirtySegmentListHead.Flink; + NewTarget = (DirtyPageCount - NewTarget + 3) / 4; + WriteCount[0] += NewTarget; + WriteCount[1] += NewTarget; + WriteCount[2] += NewTarget; + WriteCount[3] += NewTarget; } - if (*Count < NewTarget) - { - WriteCount[1] += (NewTarget - *Count); - } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); - DPRINT("CcRosFlushDirtyPages() finished\n"); + + NewTarget = WriteCount[0]; + + Target = max(NewTarget, Target); + + current_entry = DirtySegmentListHead.Flink; + if (current_entry == &DirtySegmentListHead) + { + DPRINT("No Dirty pages\n"); + } + + while (current_entry != &DirtySegmentListHead && Target > 0) + { + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + DirtySegmentListEntry); + current_entry = current_entry->Flink; + + Locked = ExTryToAcquireResourceExclusiveLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); + if (!Locked) + { + continue; + } + + Locked = ExTryToAcquirePushLockExclusive(¤t->Lock); + if (!Locked) + { + ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); + continue; + } + + ASSERT(current->Dirty); + if (current->ReferenceCount > 1) + { + ExReleasePushLock(¤t->Lock); + ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); + continue; + } + + PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE; - return(STATUS_SUCCESS); + KeReleaseGuardedMutex(&ViewLock); + + Status = CcRosFlushCacheSegment(current); + + ExReleasePushLock(¤t->Lock); + ExReleaseResourceLite(((FSRTL_COMMON_FCB_HEADER*)(current->Bcb->FileObject->FsContext))->Resource); + + if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE)) + { + DPRINT1("CC: Failed to flush cache segment.\n"); + } + else + { + (*Count) += PagesPerSegment; + Target -= PagesPerSegment; + } + + KeAcquireGuardedMutex(&ViewLock); + current_entry = DirtySegmentListHead.Flink; + } + + if (*Count < NewTarget) + { + WriteCount[1] += (NewTarget - *Count); + } + + KeReleaseGuardedMutex(&ViewLock); + + DPRINT("CcRosFlushDirtyPages() finished\n"); + return(STATUS_SUCCESS); } NTSTATUS @@ -322,7 +317,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) InitializeListHead(&FreeList); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); current_entry = CacheSegmentLRUListHead.Flink; while (current_entry != &CacheSegmentLRUListHead && Target > 0) { @@ -354,7 +349,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) last = current; current->PageOut = TRUE; KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++) { PFN_TYPE Page; @@ -365,7 +360,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) break; } } - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql); CcRosCacheSegmentDecRefCount(current); current->PageOut = FALSE; @@ -376,7 +371,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed) KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql); } } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); while (!IsListEmpty(&FreeList)) { @@ -409,7 +404,7 @@ CcRosReleaseCacheSegment(PBCB Bcb, CacheSeg->Valid = Valid; CacheSeg->Dirty = CacheSeg->Dirty || Dirty; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); if (!WasDirty && CacheSeg->Dirty) { InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); @@ -433,42 +428,43 @@ CcRosReleaseCacheSegment(PBCB Bcb, CcRosCacheSegmentIncRefCount(CacheSeg); } KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock); + KeReleaseGuardedMutex(&ViewLock); + ExReleasePushLock(&CacheSeg->Lock); return(STATUS_SUCCESS); } +/* Returns with Cache Segment Lock Held! */ PCACHE_SEGMENT NTAPI CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset) { - PLIST_ENTRY current_entry; - PCACHE_SEGMENT current; - KIRQL oldIrql; - - ASSERT(Bcb); - - DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset); - - KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - current_entry = Bcb->BcbSegmentListHead.Flink; - while (current_entry != &Bcb->BcbSegmentListHead) + PLIST_ENTRY current_entry; + PCACHE_SEGMENT current; + KIRQL oldIrql; + + ASSERT(Bcb); + + DPRINT("CcRosLookupCacheSegment(Bcb -x%p, FileOffset %d)\n", Bcb, FileOffset); + + KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); + current_entry = Bcb->BcbSegmentListHead.Flink; + while (current_entry != &Bcb->BcbSegmentListHead) { - current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, - BcbSegmentListEntry); - if (current->FileOffset <= FileOffset && - (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset) - { - CcRosCacheSegmentIncRefCount(current); - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock); - return(current); - } - current_entry = current_entry->Flink; + current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, + BcbSegmentListEntry); + if (current->FileOffset <= FileOffset && + (current->FileOffset + Bcb->CacheSegmentSize) > FileOffset) + { + CcRosCacheSegmentIncRefCount(current); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + ExAcquirePushLockExclusive(¤t->Lock); + return(current); + } + current_entry = current_entry->Flink; } - KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - return(NULL); + KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); + return(NULL); } NTSTATUS @@ -489,10 +485,10 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) } if (!CacheSeg->Dirty) { - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } else { @@ -503,7 +499,7 @@ CcRosMarkDirtyCacheSegment(PBCB Bcb, ULONG FileOffset) CacheSeg->Dirty = TRUE; - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock); + ExReleasePushLock(&CacheSeg->Lock); return(STATUS_SUCCESS); } @@ -534,10 +530,10 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) if (!WasDirty && NowDirty) { - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); InsertTailList(&DirtySegmentListHead, &CacheSeg->DirtySegmentListEntry); DirtyPageCount += Bcb->CacheSegmentSize / PAGE_SIZE; - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); @@ -552,7 +548,7 @@ CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty) } KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&CacheSeg->Lock); + ExReleasePushLock(&CacheSeg->Lock); return(STATUS_SUCCESS); } @@ -601,9 +597,9 @@ CcRosCreateCacheSegment(PBCB Bcb, current->DirtySegmentListEntry.Flink = NULL; current->DirtySegmentListEntry.Blink = NULL; current->ReferenceCount = 1; - ExInitializeFastMutex(¤t->Lock); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + ExInitializePushLock((PULONG_PTR)¤t->Lock); + ExAcquirePushLockExclusive(¤t->Lock); + KeAcquireGuardedMutex(&ViewLock); *CacheSeg = current; /* There is window between the call to CcRosLookupCacheSegment @@ -632,11 +628,11 @@ CcRosCreateCacheSegment(PBCB Bcb, current ); } #endif - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(*CacheSeg)->Lock); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + ExReleasePushLock(&(*CacheSeg)->Lock); + KeReleaseGuardedMutex(&ViewLock); ExFreeToNPagedLookasideList(&CacheSegLookasideList, *CacheSeg); *CacheSeg = current; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(¤t->Lock); + ExAcquirePushLockExclusive(¤t->Lock); return STATUS_SUCCESS; } if (current->FileOffset < FileOffset) @@ -668,7 +664,7 @@ CcRosCreateCacheSegment(PBCB Bcb, KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); InsertTailList(&CacheSegmentListHead, ¤t->CacheSegmentListEntry); InsertTailList(&CacheSegmentLRUListHead, ¤t->CacheSegmentLRUListEntry); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); #ifdef CACHE_BITMAP KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql); @@ -942,7 +938,7 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) DPRINT("CcRosFreeCacheSegment(Bcb 0x%p, CacheSeg 0x%p)\n", Bcb, CacheSeg); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); RemoveEntryList(&CacheSeg->BcbSegmentListEntry); RemoveEntryList(&CacheSeg->CacheSegmentListEntry); @@ -954,7 +950,7 @@ CcRosFreeCacheSegment(PBCB Bcb, PCACHE_SEGMENT CacheSeg) } KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); Status = CcRosInternalFreeCacheSegment(CacheSeg); return(Status); @@ -1012,7 +1008,7 @@ CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointers, } } KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(¤t->Lock); + ExReleasePushLock(¤t->Lock); CcRosCacheSegmentDecRefCount(current); KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); } @@ -1053,11 +1049,11 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) ASSERT(Bcb); Bcb->RefCount++; - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); CcFlushCache(FileObject->SectionObjectPointer, NULL, 0, NULL); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); Bcb->RefCount--; if (Bcb->RefCount == 0) { @@ -1094,7 +1090,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) #endif KeReleaseSpinLock(&Bcb->BcbLock, oldIrql); - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); ObDereferenceObject (Bcb->FileObject); while (!IsListEmpty(&FreeList)) @@ -1104,7 +1100,7 @@ CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb) Status = CcRosInternalFreeCacheSegment(current); } ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); } return(STATUS_SUCCESS); } @@ -1114,7 +1110,7 @@ NTAPI CcRosReferenceCache(PFILE_OBJECT FileObject) { PBCB Bcb; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; ASSERT(Bcb); if (Bcb->RefCount == 0) @@ -1129,7 +1125,7 @@ CcRosReferenceCache(PFILE_OBJECT FileObject) ASSERT(Bcb->BcbRemoveListEntry.Flink == NULL); } Bcb->RefCount++; - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } VOID @@ -1138,7 +1134,7 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer) { PBCB Bcb; DPRINT("CcRosSetRemoveOnClose()\n"); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); Bcb = (PBCB)SectionObjectPointer->SharedCacheMap; if (Bcb) { @@ -1148,7 +1144,7 @@ CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer) CcRosDeleteFileCache(Bcb->FileObject, Bcb); } } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } @@ -1157,7 +1153,7 @@ NTAPI CcRosDereferenceCache(PFILE_OBJECT FileObject) { PBCB Bcb; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); Bcb = (PBCB)FileObject->SectionObjectPointer->SharedCacheMap; ASSERT(Bcb); if (Bcb->RefCount > 0) @@ -1177,7 +1173,7 @@ CcRosDereferenceCache(PFILE_OBJECT FileObject) } } } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } NTSTATUS STDCALL @@ -1189,7 +1185,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject) { PBCB Bcb; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); if (FileObject->SectionObjectPointer->SharedCacheMap != NULL) { @@ -1216,7 +1212,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject) } } } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); return(STATUS_SUCCESS); } @@ -1227,7 +1223,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject) PBCB Bcb; NTSTATUS Status; - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); Bcb = FileObject->SectionObjectPointer->SharedCacheMap; if (Bcb == NULL) @@ -1248,7 +1244,7 @@ CcTryToInitializeFileCache(PFILE_OBJECT FileObject) } Status = STATUS_SUCCESS; } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); return Status; } @@ -1267,13 +1263,13 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, DPRINT("CcRosInitializeFileCache(FileObject 0x%p, Bcb 0x%p, CacheSegmentSize %d)\n", FileObject, Bcb, CacheSegmentSize); - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); if (Bcb == NULL) { Bcb = ExAllocateFromNPagedLookasideList(&BcbLookasideList); if (Bcb == NULL) { - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); return(STATUS_UNSUCCESSFUL); } memset(Bcb, 0, sizeof(BCB)); @@ -1304,7 +1300,7 @@ CcRosInitializeFileCache(PFILE_OBJECT FileObject, RemoveEntryList(&Bcb->BcbRemoveListEntry); Bcb->BcbRemoveListEntry.Flink = NULL; } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); return(STATUS_SUCCESS); } @@ -1359,7 +1355,7 @@ CmLazyCloseThreadMain(PVOID Ignored) break; } - ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&ViewLock); + KeAcquireGuardedMutex(&ViewLock); CcTimeStamp++; if (CcTimeStamp >= 30) { @@ -1375,7 +1371,7 @@ CmLazyCloseThreadMain(PVOID Ignored) CcRosDeleteFileCache(current->FileObject, current); } } - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&ViewLock); + KeReleaseGuardedMutex(&ViewLock); } } @@ -1426,7 +1422,7 @@ CcInitView(VOID) InitializeListHead(&DirtySegmentListHead); InitializeListHead(&CacheSegmentLRUListHead); InitializeListHead(&ClosedListHead); - ExInitializeFastMutex(&ViewLock); + KeInitializeGuardedMutex(&ViewLock); ExInitializeNPagedLookasideList (&iBcbLookasideList, NULL, NULL, @@ -1482,3 +1478,4 @@ CcInitView(VOID) + diff --git a/reactos/ntoskrnl/include/internal/cc.h b/reactos/ntoskrnl/include/internal/cc.h index 7e1ba8a8c58..c5d74a68893 100644 --- a/reactos/ntoskrnl/include/internal/cc.h +++ b/reactos/ntoskrnl/include/internal/cc.h @@ -145,7 +145,7 @@ typedef struct _CACHE_SEGMENT /* Offset in the file which this cache segment maps. */ ULONG FileOffset; /* Lock. */ - FAST_MUTEX Lock; + EX_PUSH_LOCK Lock; /* Number of references. */ ULONG ReferenceCount; /* Pointer to the BCB for the file which this cache segment maps data for. */ diff --git a/reactos/ntoskrnl/include/internal/ex.h b/reactos/ntoskrnl/include/internal/ex.h index 9f64e70b1da..8779d30fd25 100644 --- a/reactos/ntoskrnl/include/internal/ex.h +++ b/reactos/ntoskrnl/include/internal/ex.h @@ -719,6 +719,40 @@ ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) ASSERT(PushLock->Locked); } +/*++ +* @name ExTryToAcquirePushLockExclusive +* INTERNAL MACRO +* +* The ExAcquirePushLockExclusive macro exclusively acquires a PushLock. +* +* @params PushLock +* Pointer to the pushlock which is to be acquired. +* +* @return None. +* +* @remarks The function attempts the quickest route to acquire the lock, which is +* to simply set the lock bit. +* However, if the pushlock is already shared, the slower path is taken. +* +* Callers of ExAcquirePushLockShared must be running at IRQL <= APC_LEVEL. +* This macro should usually be paired up with KeAcquireCriticalRegion. +* +*--*/ +BOOLEAN +FORCEINLINE +ExTryToAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) +{ + /* Try acquiring the lock */ + if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V)) + { + /* Can't acquire */ + return FALSE; + } + + /* Got acquired */ + return TRUE; +} + /*++ * @name ExAcquirePushLockShared * INTERNAL MACRO diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 0a6ac154d0d..1d66c742d51 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -118,7 +118,7 @@ extern KTSS KiBootTss; #endif extern UCHAR P0BootStack[]; extern UCHAR KiDoubleFaultStack[]; -extern FAST_MUTEX KernelAddressSpaceLock; +extern EX_PUSH_LOCK KernelAddressSpaceLock; extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate; extern ULONG KiAdjustDpcThreshold; diff --git a/reactos/ntoskrnl/mm/aspace.c b/reactos/ntoskrnl/mm/aspace.c index 3d92d90a866..78c6883cc2d 100644 --- a/reactos/ntoskrnl/mm/aspace.c +++ b/reactos/ntoskrnl/mm/aspace.c @@ -21,7 +21,7 @@ /* GLOBALS ******************************************************************/ static MADDRESS_SPACE KernelAddressSpace; -FAST_MUTEX KernelAddressSpaceLock; +EX_PUSH_LOCK KernelAddressSpaceLock; /* FUNCTIONS *****************************************************************/ @@ -29,21 +29,13 @@ VOID NTAPI MmLockAddressSpace(PMADDRESS_SPACE AddressSpace) { - /* - * Don't bother with locking if we are the first thread. - */ - if (KeGetCurrentThread() == NULL) - { - return; - } - if (AddressSpace->Process) { - ExEnterCriticalRegionAndAcquireFastMutexUnsafe((PFAST_MUTEX)&AddressSpace->Process->AddressCreationLock); + ExAcquirePushLockExclusive((PEX_PUSH_LOCK)&AddressSpace->Process->AddressCreationLock); } else { - ExEnterCriticalRegionAndAcquireFastMutexUnsafe((PFAST_MUTEX)&KernelAddressSpaceLock); + ExAcquirePushLockExclusive(&KernelAddressSpaceLock); } } @@ -51,20 +43,13 @@ VOID NTAPI MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace) { - /* - * Don't bother locking if we are the first thread. - */ - if (KeGetCurrentThread() == NULL) - { - return; - } if (AddressSpace->Process) { - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((PFAST_MUTEX)&AddressSpace->Process->AddressCreationLock); + ExReleasePushLock((PEX_PUSH_LOCK)&AddressSpace->Process->AddressCreationLock); } else { - ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((PFAST_MUTEX)&KernelAddressSpaceLock); + ExReleasePushLock(&KernelAddressSpaceLock); } } @@ -98,11 +83,11 @@ MmInitializeAddressSpace(PEPROCESS Process, AddressSpace->MemoryAreaRoot = NULL; if (Process) { - ExInitializeFastMutex((PFAST_MUTEX)&Process->AddressCreationLock); + ExInitializePushLock((PULONG_PTR)&Process->AddressCreationLock); } else { - ExInitializeFastMutex((PFAST_MUTEX)&KernelAddressSpaceLock); + ExInitializePushLock((PULONG_PTR)&KernelAddressSpaceLock); } if (Process != NULL) { diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 0e8419c65ed..07280944818 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -55,6 +55,17 @@ #pragma alloc_text(INIT, MmInitSectionImplementation) #endif +FORCEINLINE +VOID +sprintf_nt(IN PCHAR Buffer, + IN PCHAR Format, + IN ...) +{ + va_list ap; + va_start(ap, Format); + vsprintf(Buffer, Format, ap); + va_end(ap); +} /* TYPES *********************************************************************/ @@ -4506,6 +4517,9 @@ MmMapViewOfSection(IN PVOID SectionObject, PROS_SECTION_OBJECT Section; PMADDRESS_SPACE AddressSpace; ULONG ViewOffset; + //ANSI_STRING AnsiTemp; + //PCHAR Buffer; + NTSTATUS Status = STATUS_SUCCESS; ASSERT(Process); @@ -4608,6 +4622,41 @@ MmMapViewOfSection(IN PVOID SectionObject, } *BaseAddress = (PVOID)ImageBase; + + /* Notify debugger about image being loaded */ + if (NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD) + { +#ifdef KDBG + /* If KDBG is defined, then we always have symbols */ + if (TRUE) +#else + if (MiCacheImageSymbols(ImageBase)) +#endif + { +#if 0 + MmUnlockAddressSpace(AddressSpace); + + /* Allocate a buffer we'll use for names */ + Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, TAG_LDR_WSTR); + if (Buffer) + { + /* Build the name */ + sprintf_nt(Buffer, "%wZ", &Section->FileObject->FileName); + + /* Setup the ansi string */ + RtlInitString(&AnsiTemp, Buffer); + + /* Notify the debugger */ + DbgLoadImageSymbols(&AnsiTemp, (PVOID)ImageBase, (ULONG_PTR)Process); + + /* Free allocated buffer */ + ExFreePool(Buffer); + } + + MmLockAddressSpace(AddressSpace); +#endif + } + } } else {