mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:45:40 +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 BcbLookasideList;
|
||||||
static NPAGED_LOOKASIDE_LIST CacheSegLookasideList;
|
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__)
|
#if defined(__GNUC__)
|
||||||
/* void * alloca(size_t size); */
|
/* void * alloca(size_t size); */
|
||||||
|
@ -309,7 +304,7 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PCACHE_SEGMENT current, last = NULL;
|
PCACHE_SEGMENT current;
|
||||||
ULONG PagesPerSegment;
|
ULONG PagesPerSegment;
|
||||||
ULONG PagesFreed;
|
ULONG PagesFreed;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
@ -325,10 +320,54 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
||||||
current_entry = CacheSegmentLRUListHead.Flink;
|
current_entry = CacheSegmentLRUListHead.Flink;
|
||||||
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
|
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
|
||||||
CacheSegmentLRUListEntry);
|
CacheSegmentLRUListEntry);
|
||||||
current_entry = current_entry->Flink;
|
current_entry = current_entry->Flink;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||||
|
|
||||||
|
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);
|
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
|
||||||
if (current->ReferenceCount == 0)
|
if (current->ReferenceCount == 0)
|
||||||
{
|
{
|
||||||
|
@ -337,44 +376,13 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
||||||
RemoveEntryList(¤t->CacheSegmentListEntry);
|
RemoveEntryList(¤t->CacheSegmentListEntry);
|
||||||
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
RemoveEntryList(¤t->CacheSegmentLRUListEntry);
|
||||||
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
|
||||||
PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
|
|
||||||
PagesFreed = min(PagesPerSegment, Target);
|
|
||||||
Target -= PagesFreed;
|
|
||||||
(*NrFreed) += PagesFreed;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (last != current && current->MappedCount > 0 && !current->Dirty && !current->PageOut)
|
KeReleaseSpinLock(¤t->Bcb->BcbLock, oldIrql);
|
||||||
{
|
}
|
||||||
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);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
|
|
||||||
while (!IsListEmpty(&FreeList))
|
while (!IsListEmpty(&FreeList))
|
||||||
|
@ -385,7 +393,6 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
||||||
CcRosInternalFreeCacheSegment(current);
|
CcRosInternalFreeCacheSegment(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("CcRosTrimCache() finished\n");
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,16 +1158,8 @@ CcRosDereferenceCache(PFILE_OBJECT FileObject)
|
||||||
if (Bcb->RefCount == 0)
|
if (Bcb->RefCount == 0)
|
||||||
{
|
{
|
||||||
MmFreeSectionSegments(Bcb->FileObject);
|
MmFreeSectionSegments(Bcb->FileObject);
|
||||||
if (Bcb->RemoveOnClose)
|
|
||||||
{
|
|
||||||
CcRosDeleteFileCache(FileObject, Bcb);
|
CcRosDeleteFileCache(FileObject, Bcb);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Bcb->TimeStamp = CcTimeStamp;
|
|
||||||
InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
KeReleaseGuardedMutex(&ViewLock);
|
KeReleaseGuardedMutex(&ViewLock);
|
||||||
}
|
}
|
||||||
|
@ -1188,16 +1187,8 @@ CcRosReleaseFileCache(PFILE_OBJECT FileObject)
|
||||||
if (Bcb->RefCount == 0)
|
if (Bcb->RefCount == 0)
|
||||||
{
|
{
|
||||||
MmFreeSectionSegments(Bcb->FileObject);
|
MmFreeSectionSegments(Bcb->FileObject);
|
||||||
if (Bcb->RemoveOnClose)
|
|
||||||
{
|
|
||||||
CcRosDeleteFileCache(FileObject, Bcb);
|
CcRosDeleteFileCache(FileObject, Bcb);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Bcb->TimeStamp = CcTimeStamp;
|
|
||||||
InsertHeadList(&ClosedListHead, &Bcb->BcbRemoveListEntry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1315,60 +1306,6 @@ CcGetFileObjectFromSectionPtrs(IN PSECTION_OBJECT_POINTERS SectionObjectPointers
|
||||||
return NULL;
|
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
|
VOID
|
||||||
INIT_FUNCTION
|
INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1379,8 +1316,6 @@ CcInitView(VOID)
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
#endif
|
#endif
|
||||||
NTSTATUS Status;
|
|
||||||
KPRIORITY Priority;
|
|
||||||
|
|
||||||
DPRINT("CcInitView()\n");
|
DPRINT("CcInitView()\n");
|
||||||
#ifdef CACHE_BITMAP
|
#ifdef CACHE_BITMAP
|
||||||
|
@ -1443,25 +1378,6 @@ CcInitView(VOID)
|
||||||
|
|
||||||
CcInitCacheZeroPage();
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -684,7 +684,7 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable,
|
||||||
ULONG BootPhase)
|
ULONG BootPhase)
|
||||||
{
|
{
|
||||||
PCHAR p1, p2;
|
PCHAR p1, p2;
|
||||||
SHORT Found;
|
SHORT Found = FALSE;
|
||||||
CHAR YesNo;
|
CHAR YesNo;
|
||||||
LIST_ENTRY *ModuleEntry;
|
LIST_ENTRY *ModuleEntry;
|
||||||
PLDR_DATA_TABLE_ENTRY DataTableEntry;
|
PLDR_DATA_TABLE_ENTRY DataTableEntry;
|
||||||
|
@ -708,12 +708,6 @@ KdbInitialize(PKD_DISPATCH_TABLE DispatchTable,
|
||||||
InitializeListHead(&SymbolFileListHead);
|
InitializeListHead(&SymbolFileListHead);
|
||||||
KeInitializeSpinLock(&SymbolFileListLock);
|
KeInitializeSpinLock(&SymbolFileListLock);
|
||||||
|
|
||||||
#ifdef DBG
|
|
||||||
LoadSymbols = TRUE;
|
|
||||||
#else
|
|
||||||
LoadSymbols = FALSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
|
/* Check the command line for /LOADSYMBOLS, /NOLOADSYMBOLS,
|
||||||
* /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
|
* /LOADSYMBOLS={YES|NO}, /NOLOADSYMBOLS={YES|NO} */
|
||||||
ASSERT(KeLoaderBlock);
|
ASSERT(KeLoaderBlock);
|
||||||
|
|
|
@ -68,7 +68,18 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
|
||||||
|
|
||||||
/* Set up targets. */
|
/* Set up targets. */
|
||||||
MiMinimumAvailablePages = 64;
|
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 =
|
MiMemoryConsumers[MC_USER].PagesTarget =
|
||||||
NrAvailablePages - MiMinimumAvailablePages;
|
NrAvailablePages - MiMinimumAvailablePages;
|
||||||
MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2;
|
MiMemoryConsumers[MC_PPOOL].PagesTarget = NrAvailablePages / 2;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue