home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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(¤tContext) )
- {
- 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;
- }
-
- }
-