mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 05:51:44 +00:00
- Fix for Bug 703.
- ReactOS can now be installed on systems with as little as 24MB. Memory usage after boot is down by 20-30MB. Application installations will use/require/leak less memory. - Patch by Alex Ionescu. See issue #703 for more details. svn path=/trunk/; revision=39663
This commit is contained in:
parent
cac6a6eb40
commit
a4718924aa
3 changed files with 101 additions and 180 deletions
|
@ -70,11 +70,6 @@ NPAGED_LOOKASIDE_LIST iBcbLookasideList;
|
|||
static NPAGED_LOOKASIDE_LIST BcbLookasideList;
|
||||
static NPAGED_LOOKASIDE_LIST CacheSegLookasideList;
|
||||
|
||||
static ULONG CcTimeStamp;
|
||||
static KEVENT LazyCloseThreadEvent;
|
||||
static HANDLE LazyCloseThreadHandle;
|
||||
static CLIENT_ID LazyCloseThreadId;
|
||||
static volatile BOOLEAN LazyCloseThreadShouldTerminate;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/* void * alloca(size_t size); */
|
||||
|
@ -308,85 +303,97 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
|||
* actually freed is returned.
|
||||
*/
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PCACHE_SEGMENT current, last = NULL;
|
||||
ULONG PagesPerSegment;
|
||||
ULONG PagesFreed;
|
||||
KIRQL oldIrql;
|
||||
LIST_ENTRY FreeList;
|
||||
PLIST_ENTRY current_entry;
|
||||
PCACHE_SEGMENT current;
|
||||
ULONG PagesPerSegment;
|
||||
ULONG PagesFreed;
|
||||
KIRQL oldIrql;
|
||||
LIST_ENTRY FreeList;
|
||||
|
||||
DPRINT("CcRosTrimCache(Target %d)\n", Target);
|
||||
|
||||
*NrFreed = 0;
|
||||
|
||||
InitializeListHead(&FreeList);
|
||||
|
||||
DPRINT("CcRosTrimCache(Target %d)\n", Target);
|
||||
|
||||
*NrFreed = 0;
|
||||
|
||||
InitializeListHead(&FreeList);
|
||||
|
||||
KeAcquireGuardedMutex(&ViewLock);
|
||||
current_entry = CacheSegmentLRUListHead.Flink;
|
||||
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
|
||||
KeAcquireGuardedMutex(&ViewLock);
|
||||
current_entry = CacheSegmentLRUListHead.Flink;
|
||||
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||
CacheSegmentLRUListEntry);
|
||||
current_entry = current_entry->Flink;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||
CacheSegmentLRUListEntry);
|
||||
current_entry = current_entry->Flink;
|
||||
|
||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||
|
||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||
if (current->ReferenceCount == 0)
|
||||
{
|
||||
RemoveEntryList(¤t->BcbSegmentListEntry);
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
||||
PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
|
||||
PagesFreed = min(PagesPerSegment, Target);
|
||||
Target -= PagesFreed;
|
||||
(*NrFreed) += PagesFreed;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (last != current && current->MappedCount > 0 && !current->Dirty && !current->PageOut)
|
||||
{
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
CcRosCacheSegmentIncRefCount(current);
|
||||
last = current;
|
||||
current->PageOut = TRUE;
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
|
||||
{
|
||||
PFN_TYPE Page;
|
||||
Page = (PFN_TYPE)(MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
|
||||
Status = MmPageOutPhysicalAddress(Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
KeAcquireGuardedMutex(&ViewLock);
|
||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||
CcRosCacheSegmentDecRefCount(current);
|
||||
current->PageOut = FALSE;
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
current_entry = ¤t->CacheSegmentLRUListEntry;
|
||||
continue;
|
||||
}
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
}
|
||||
}
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
|
||||
while (!IsListEmpty(&FreeList))
|
||||
{
|
||||
current_entry = RemoveHeadList(&FreeList);
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||
BcbSegmentListEntry);
|
||||
CcRosInternalFreeCacheSegment(current);
|
||||
}
|
||||
|
||||
DPRINT("CcRosTrimCache() finished\n");
|
||||
return(STATUS_SUCCESS);
|
||||
if (current->MappedCount > 0 && !current->Dirty && !current->PageOut)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
CcRosCacheSegmentIncRefCount(current);
|
||||
current->PageOut = TRUE;
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
|
||||
{
|
||||
PFN_TYPE Page;
|
||||
Page = (PFN_TYPE)(MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
|
||||
Status = MmPageOutPhysicalAddress(Page);
|
||||
}
|
||||
KeAcquireGuardedMutex(&ViewLock);
|
||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||
CcRosCacheSegmentDecRefCount(current);
|
||||
}
|
||||
|
||||
if (current->ReferenceCount == 0)
|
||||
{
|
||||
PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
|
||||
// PagesFreed = PagesPerSegment;
|
||||
PagesFreed = min(PagesPerSegment, Target);
|
||||
Target -= PagesFreed;
|
||||
(*NrFreed) += PagesFreed;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
}
|
||||
|
||||
current_entry = CacheSegmentLRUListHead.Flink;
|
||||
while (current_entry != &CacheSegmentLRUListHead)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||
CacheSegmentLRUListEntry);
|
||||
current->PageOut = FALSE;
|
||||
current_entry = current_entry->Flink;
|
||||
|
||||
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||
if (current->ReferenceCount == 0)
|
||||
{
|
||||
RemoveEntryList(¤t->BcbSegmentListEntry);
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||
}
|
||||
}
|
||||
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
|
||||
while (!IsListEmpty(&FreeList))
|
||||
{
|
||||
current_entry = RemoveHeadList(&FreeList);
|
||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||
BcbSegmentListEntry);
|
||||
CcRosInternalFreeCacheSegment(current);
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@ -1151,15 +1158,7 @@ CcRosDereferenceCache(PFILE_OBJECT FileObject)
|
|||
if (Bcb->RefCount == 0)
|
||||
{
|
||||
MmFreeSectionSegments(Bcb->FileObject);
|
||||
if (Bcb->RemoveOnClose)
|
||||
{
|
||||
CcRosDeleteFileCache(FileObject, Bcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bcb->TimeStamp = CcTimeStamp;
|
||||
InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
|
@ -1188,15 +1187,7 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
|
|||
if (Bcb->RefCount == 0)
|
||||
{
|
||||
MmFreeSectionSegments(Bcb->FileObject);
|
||||
if (Bcb->RemoveOnClose)
|
||||
{
|
||||
CcRosDeleteFileCache(FileObject, Bcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
Bcb->TimeStamp = CcTimeStamp;
|
||||
InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1315,60 +1306,6 @@ CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers
|
|||
return NULL;
|
||||
}
|
||||
|
||||
VOID NTAPI
|
||||
CmLazyCloseThreadMain(PVOID Ignored)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
PLIST_ENTRY current_entry;
|
||||
PBCB current;
|
||||
ULONG RemoveTimeStamp;
|
||||
NTSTATUS Status;
|
||||
|
||||
KeQuerySystemTime (&Timeout);
|
||||
|
||||
while (1)
|
||||
{
|
||||
Timeout.QuadPart += (LONGLONG)100000000; // 10sec
|
||||
Status = KeWaitForSingleObject(&LazyCloseThreadEvent,
|
||||
0,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
&Timeout);
|
||||
|
||||
DPRINT("LazyCloseThreadMain %d\n", CcTimeStamp);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("LazyCloseThread: Wait failed\n");
|
||||
KeBugCheck(CACHE_MANAGER);
|
||||
break;
|
||||
}
|
||||
if (LazyCloseThreadShouldTerminate)
|
||||
{
|
||||
DbgPrint("LazyCloseThread: Terminating\n");
|
||||
break;
|
||||
}
|
||||
|
||||
KeAcquireGuardedMutex(&ViewLock);
|
||||
CcTimeStamp++;
|
||||
if (CcTimeStamp >= 30)
|
||||
{
|
||||
RemoveTimeStamp = CcTimeStamp - 30; /* 5min = 10sec * 30 */
|
||||
while (!IsListEmpty(&ClosedListHead))
|
||||
{
|
||||
current_entry = ClosedListHead.Blink;
|
||||
current = CONTAINING_RECORD(current_entry, BCB, BcbRemoveListEntry);
|
||||
if (current->TimeStamp >= RemoveTimeStamp)
|
||||
{
|
||||
break;
|
||||
}
|
||||
CcRosDeleteFileCache(current->FileObject, current);
|
||||
}
|
||||
}
|
||||
KeReleaseGuardedMutex(&ViewLock);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
|
@ -1379,8 +1316,6 @@ CcInitView(VOID)
|
|||
PVOID Buffer;
|
||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||
#endif
|
||||
NTSTATUS Status;
|
||||
KPRIORITY Priority;
|
||||
|
||||
DPRINT("CcInitView()\n");
|
||||
#ifdef CACHE_BITMAP
|
||||
|
@ -1443,25 +1378,6 @@ CcInitView(VOID)
|
|||
|
||||
CcInitCacheZeroPage();
|
||||
|
||||
CcTimeStamp = 0;
|
||||
LazyCloseThreadShouldTerminate = FALSE;
|
||||
KeInitializeEvent (&LazyCloseThreadEvent, SynchronizationEvent, FALSE);
|
||||
Status = PsCreateSystemThread(&LazyCloseThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
&LazyCloseThreadId,
|
||||
(PKSTART_ROUTINE)CmLazyCloseThreadMain,
|
||||
NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Priority = LOW_REALTIME_PRIORITY;
|
||||
NtSetInformationThread(LazyCloseThreadHandle,
|
||||
ThreadPriority,
|
||||
&Priority,
|
||||
sizeof(Priority));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -684,7 +684,7 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable,
|
|||
ULONG BootPhase)
|
||||
{
|
||||
PCHAR p1, p2;
|
||||
SHORT Found;
|
||||
SHORT Found = FALSE;
|
||||
CHAR YesNo;
|
||||
LIST_ENTRY *ModuleEntry;
|
||||
PLDR_DATA_TABLE_ENTRY DataTableEntry;
|
||||
|
@ -708,12 +708,6 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable,
|
|||
InitializeListHead(&SymbolFileListHead);
|
||||
KeInitializeSpinLock(&SymbolFileListLock);
|
||||
|
||||
#ifdef DBG
|
||||
LoadSymbols = TRUE;
|
||||
#else
|
||||
LoadSymbols = FALSE;
|
||||
#endif
|
||||
|
||||
/* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
|
||||
* /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
|
||||
ASSERT(KeLoaderBlock);
|
||||
|
|
|
@ -68,7 +68,18 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
|
|||
|
||||
/* Set up targets. */
|
||||
MiMinimumAvailablePages = 64;
|
||||
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 2;
|
||||
if ((NrAvailablePages + NrSystemPages) >= 8192)
|
||||
{
|
||||
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
|
||||
}
|
||||
else if ((NrAvailablePages + NrSystemPages) >= 4096)
|
||||
{
|
||||
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 3 * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
|
||||
}
|
||||
MiMemoryConsumers[MC_USER].PagesTarget =
|
||||
NrAvailablePages - MiMinimumAvailablePages;
|
||||
MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue