pjs/cmd/macfe/utility/fredmem.cp

277 строки
6.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef NSPR20
#include "prmacos.h"
#endif
#include "fredmem.h"
#include "shist.h"
#include "shistele.h"
#include "lo_ele.h"
#include "proto.h"
#include "net.h"
#include "libimg.h"
#include "fe_proto.h"
#include "uerrmgr.h"
#include "PascalString.h"
#include "resgui.h"
#include "MacMemAllocator.h"
//#include "MToolkit.h"
enum {
kEmergencyMemoryFundSize = 64 * 1024
};
class LMallocFlusherPeriodical : public LPeriodical {
public:
LMallocFlusherPeriodical();
virtual void SpendTime(const EventRecord &inMacEvent);
void FlushMemory ( void ) { mFlushMemory = true; }
private:
Boolean mFlushMemory;
};
class LLowMallocWarningPeriodical : public LPeriodical {
public:
LLowMallocWarningPeriodical();
virtual void SpendTime(const EventRecord &inMacEvent);
void WarnUserMallocLow ( void ) { mWarnUser = true; }
private:
Boolean mWarnUser;
};
unsigned char MacFEMemoryFlusher ( size_t bytesNeeded );
void ImageCacheMemoryFlusher(void);
void LayoutCacheMemoryFlusher(void);
void NetlibCacheMemoryFlusher(void);
void LibNeoCacheMemoryFlusher(void);
void MallocIsLowWarning(void);
static LMallocFlusherPeriodical gMallocFlusher;
static LLowMallocWarningPeriodical gMallocWarner;
void Memory_InitializeMemory()
{
new LGrowZone(kEmergencyMemoryFundSize);
new LMemoryFlusherListener();
InstallMemoryCacheFlusher(&MacFEMemoryFlusher);
// install our low memory (malloc heap) warning proc
InstallMallocHeapLowProc ( &MallocIsLowWarning );
}
void Memory_DoneWithMemory()
{
// No cleanup necessary
}
size_t Memory_MaxApplMem()
{
return 0;
}
Boolean Memory_MemoryIsLow()
{
return (LGrowZone::GetGrowZone())->MemoryIsLow();
}
//##############################################################################
//##############################################################################
#pragma mark MAC FE MEMORY FLUSH PROC
unsigned char MacFEMemoryFlusher ( size_t bytesNeeded )
{
/* signal the flusher to do it's thing. I would rather start the idler here */
/* but that involves allocating memory (and so could be reentrant)... */
gMallocFlusher.FlushMemory();
return 0;
}
//##############################################################################
//##############################################################################
#pragma mark LAYOUT CACHE FLUSHING
LArray sFlushableLayoutContextList;
void FM_SetFlushable(MWContext* context, Boolean canFlush)
{
if (canFlush) {
if (sFlushableLayoutContextList.FetchIndexOf(&context) == 0)
sFlushableLayoutContextList.InsertItemsAt(1, LArray::index_Last, &context);
}
else {
sFlushableLayoutContextList.Remove(&context);
}
}
void LayoutCacheMemoryFlusher(void)
{
MWContext *currentContext = NULL;
SInt32 bytesFreed = 0;
LArrayIterator iter(sFlushableLayoutContextList);
// go ahead and empty all the recycling bins
while ( iter.Previous(&currentContext) )
{
bytesFreed += LO_EmptyRecyclingBin(currentContext);
sFlushableLayoutContextList.RemoveItemsAt( 1, 1 );
}
}
//##############################################################################
//##############################################################################
#pragma mark LIBNEO CACHE FLUSHING
void LibNeoCacheMemoryFlusher(void)
{
// don't do this yet until we really understand how safe it is
#if 0
// we don't really know how much was freed here
NeoOutOfMemHandler();
#endif
}
//##############################################################################
//##############################################################################
#pragma mark NETLIB CACHE FLUSHING
void NetlibCacheMemoryFlusher(void)
{
size_t newCacheSize;
size_t lastCacheSize;
newCacheSize = NET_GetMemoryCacheSize();
// shrink as much as we can
do {
lastCacheSize = newCacheSize;
newCacheSize = NET_RemoveLastMemoryCacheObject();
}
while ( newCacheSize != lastCacheSize );
}
//##############################################################################
//##############################################################################
#pragma mark IMAGE CACHE FLUSHING
void ImageCacheMemoryFlusher(void)
{
size_t newCacheSize;
size_t lastCacheSize;
newCacheSize = IL_GetCacheSize();
// shrink as much as we can
do {
lastCacheSize = newCacheSize;
newCacheSize = IL_ShrinkCache();
}
while ( newCacheSize != lastCacheSize );
}
//##############################################################################
//##############################################################################
#pragma mark MALLOC HEAP LOW USER WARNING
void MallocIsLowWarning(void)
{
gMallocWarner.WarnUserMallocLow();
}
//##############################################################################
//##############################################################################
#pragma mark GROW ZONE LISTENER
LMemoryFlusherListener::
LMemoryFlusherListener():LListener()
{
(LGrowZone::GetGrowZone())->AddListener(this);
}
void
LMemoryFlusherListener::ListenToMessage(MessageT inMessage, void *ioParam)
{
Int32 *bytesToFree = (Int32 *)ioParam;
if (inMessage == msg_GrowZone) {
UInt8 successfulFlush = false;
/* we don't do anything here yet */
if (!successfulFlush)
*bytesToFree = 0;
}
}
//##############################################################################
//##############################################################################
#pragma mark MEMORY PERIODICAL
LLowMallocWarningPeriodical::LLowMallocWarningPeriodical() : LPeriodical()
{
mWarnUser = false;
StartIdling();
}
void
LLowMallocWarningPeriodical::SpendTime(const EventRecord &inMacEvent)
{
if ( mWarnUser )
{
StopIdling();
FE_Alert( NULL, GetPString ( MALLOC_HEAP_LOW_RESID ) );
}
}
LMallocFlusherPeriodical::LMallocFlusherPeriodical() : LPeriodical()
{
mFlushMemory = false;
StartIdling();
}
void
LMallocFlusherPeriodical::SpendTime(const EventRecord &inMacEvent)
{
if ( mFlushMemory )
{
ImageCacheMemoryFlusher();
LayoutCacheMemoryFlusher();
NetlibCacheMemoryFlusher();
LibNeoCacheMemoryFlusher();
mFlushMemory = false;
}
}