--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfile/sf_memory_man.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,347 @@
+// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// f32\sfile\sf_memory_man.cpp
+//
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+
+#include <e32std.h>
+#include <e32std_private.h>
+#include "sf_std.h"
+#include <e32uid.h>
+#include <e32wins.h>
+#include <f32file.h>
+#include <hal.h>
+#include "sf_memory_man.h"
+#include "sf_memory_client.h"
+
+/**
+Destructor of the CCacheMemoryManager, need to destroy all registered clients.
+*/
+CCacheMemoryManager::~CCacheMemoryManager()
+ {
+ for (TInt i = 0; i < iRegisteredClients.Count(); i++)
+ {
+ iRegisteredClients[i]->Reset();
+ delete iRegisteredClients[i];
+ }
+ iRegisteredClients.Close();
+ }
+
+/**
+Static factory function of CCacheMemoryManager
+@param aCacheSize the total size of the virtual address space
+*/
+CCacheMemoryManager* CCacheMemoryManager::NewL(TInt aCacheSize)
+ {
+ CCacheMemoryManager* cacheMemoryManager = new (ELeave) CCacheMemoryManager(aCacheSize);
+
+ CleanupStack::PushL(cacheMemoryManager);
+ cacheMemoryManager->ConstructL();
+ CleanupStack::Pop(1, cacheMemoryManager);
+
+ return cacheMemoryManager;
+ }
+
+/**
+Constructor of CCacheMemoryManager
+@param aMaxSize the total size of the virtual address space
+*/
+CCacheMemoryManager::CCacheMemoryManager(TUint32 aMaxSize)
+:iBase(NULL),
+iSizeInBytes(aMaxSize),
+iCurrentOffsetMark(0)
+ {
+ }
+
+/**
+Second phase constructor of CCacheMemoryManager.
+Creates RChunk object and sets low memory threshold.
+*/
+void CCacheMemoryManager::ConstructL()
+ {
+ // calculate the low-memory threshold below which we fail any attempt to allocate memory
+ TMemoryInfoV1Buf meminfo;
+ TInt r = UserHal::MemoryInfo(meminfo);
+ ASSERT(r==KErrNone);
+ User::LeaveIfError(r);
+ iLowMemoryThreshold = (meminfo().iTotalRamInBytes * TGlobalCacheMemorySettings::LowMemoryThreshold()) / 100;
+ TChunkCreateInfo createInfo;
+ createInfo.SetCache(iSizeInBytes);
+ createInfo.SetOwner(EOwnerProcess);
+ r = iChunk.Create(createInfo);
+ ASSERT(r==KErrNone);
+ User::LeaveIfError(r);
+ UserSvr::RegisterTrustedChunk(iChunk.Handle());
+ iBase = iChunk.Base();
+ iRegisteredClients.ReserveL(10);
+ __PRINT3(_L("CCacheMemoryManager::ConstructL(lowMem=%d, iSize=%d, base=0x%lx)"), iLowMemoryThreshold, iSizeInBytes, iBase);
+ }
+
+/**
+Connect or register a client.
+Note: callers of this function should be constructor of various caches, it is their resposibility
+ to make sure that parameters are sensible when calling this function
+
+@internalTechnology
+@released
+
+@param aClientName an identifier of the client to be connected
+@param aMinSizeInSegs minimum client size in segments
+@param aMaxSizeInSegs maximum client size in segments
+@return CCacheMemoryClient* pointer to the client that connected, or NULL if parameters are not valid.
+@leave if no memory
+*/
+EXPORT_C CCacheMemoryClient* CCacheMemoryManager::ConnectClientL(const TDesC& aClientName, TUint32 aMinSizeInSegs, TUint32 aMaxSizeInSegs)
+ {
+ __PRINT3(_L("CCacheMemoryManager::ConnectClientL: [%S], minSeg=%d, maxSeg=%d"), &aClientName, aMinSizeInSegs, aMaxSizeInSegs);
+ for (TInt i = 0; i < iRegisteredClients.Count(); i++)
+ {
+ if (aClientName.Compare(iRegisteredClients[i]->Name()) == 0)
+ {
+ ASSERT(iRegisteredClients[i]->iTouchedRegionFlag == 0);
+ __PRINT1(_L("CCacheMemoryManager::ConnectClientL: [%S] found!"), &aClientName);
+ return iRegisteredClients[i];
+ }
+ }
+
+ // parameter validation
+ ASSERT(iSizeInBytes > iCurrentOffsetMark + (aMaxSizeInSegs << SegmentSizeInBytesLog2()));
+ if (iSizeInBytes < iCurrentOffsetMark + (aMaxSizeInSegs << SegmentSizeInBytesLog2()))
+ {
+ ASSERT(0);
+ return NULL;
+ }
+
+ // if not found in registered clients, creates new
+ // this may leave under OOM condition
+ CCacheMemoryClient* client = CCacheMemoryClient::NewL(*this, aClientName, iCurrentOffsetMark, aMinSizeInSegs, aMaxSizeInSegs);
+
+ // if error happens during client registration, the client will be deleted
+ // this may leave under OOM condition
+ TInt err = iRegisteredClients.Append(client);
+ if (err != KErrNone)
+ {
+ ASSERT(0);
+ delete client;
+ client = NULL;
+ User::Leave(err);
+ }
+
+ // record current offset mark for next client
+ iCurrentOffsetMark += (aMaxSizeInSegs << SegmentSizeInBytesLog2());
+ return client;
+ }
+
+/**
+Commit a contiguous set of segments.
+@param aStartRamAddr the start ram address of the region to be committed.
+@param aSegmentCount the segment number of the contiguous region to be committed.
+@return TInt KErrNone if succeeded, KErrNoMemory if passed low memory threshold, otherwise a system-wide error code.
+*/
+TInt CCacheMemoryManager::AllocateAndLockSegments(TUint8* aStartRamAddr, TInt aSegmentCount)
+ {
+ __PRINT2(_L("CCacheMemoryManager::AllocateAndLockSegments: base=0x%x, seg=%d"), aStartRamAddr, aSegmentCount);
+ TMemoryInfoV1Buf meminfo;
+ TInt r = UserHal::MemoryInfo(meminfo);
+ __ASSERT_DEBUG(r==KErrNone,Fault(EMemoryInfoFailed));
+ if (r != KErrNone)
+ {
+ return r;
+ }
+
+ if (isMemoryLow || (meminfo().iFreeRamInBytes < iLowMemoryThreshold))
+ {
+ __PRINT(_L("CCacheMemoryManager: free RAM below threshold !!!"));
+ return KErrNoMemory;
+ }
+ return Commit(aStartRamAddr, aSegmentCount);
+ }
+
+/**
+Notify the change of memory status
+@param aIsMemoryLow the flag that sets current memory status
+*/
+void CCacheMemoryManager::FreeMemoryChanged(TBool aIsMemoryLow)
+ {
+ isMemoryLow = aIsMemoryLow;
+ }
+
+/**
+Decommit a contiguous set of segments.
+@param aStartRamAddr the start ram address of the region to be decommitted.
+@param aSegmentCount the segment number of the contiguous region to be decommitted.
+@return TInt KErrNone if succeeded, otherwise a system-wide error code.
+*/
+TInt CCacheMemoryManager::DecommitSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
+ {
+ return Decommit(aStartRamAddr, aSegmentCount);
+ }
+
+/**
+Lock a contiguous set of segments.
+@param aStartRamAddr the start ram address of the region to be locked.
+@param aSegmentCount the segment number of the contiguous region to be locked.
+@return TInt KErrNone if succeeded, otherwise a system-wide error code.
+*/
+TInt CCacheMemoryManager::LockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
+ {
+ return Lock(aStartRamAddr, aSegmentCount);
+ }
+
+/**
+Unlock a contiguous set of segments.
+@param aStartRamAddr the start ram address of the region to be unlocked.
+@param aSegmentCount the segment number of the contiguous region to be unlocked.
+@return TInt KErrNone if succeeded, otherwise a system-wide error code.
+*/
+TInt CCacheMemoryManager::UnlockSegments(TUint8* aStartRamAddr, TUint32 aSegmentCount)
+ {
+ return Unlock(aStartRamAddr, aSegmentCount);
+ }
+
+/**
+Commit a contiguous set of segments.
+@param aStartRamAddr the start ram address of the region to be committed.
+@param aSegmentCount the segment number of the contiguous region to be committed.
+@return TInt KErrNone if succeeded, otherwise a system-wide error code.
+*/
+TInt CCacheMemoryManager::Commit(TUint8* aStartRamAddr, TInt aSegmentCount)
+ {
+ TInt offset = aStartRamAddr - iBase;
+ TInt r = iChunk.Commit(offset, aSegmentCount << KSegmentSizeLog2);
+ return r;
+ }
+
+/**
+Actual implementation of DecommitSegments().
+@see CCacheMemoryManager::DecommitSegments().
+*/
+TInt CCacheMemoryManager::Decommit(TUint8* aStartRamAddr, TInt aSegmentCount)
+ {
+ return iChunk.Decommit(aStartRamAddr - iBase, aSegmentCount << KSegmentSizeLog2);
+ }
+
+/**
+Actual implementation of UnlockSegments().
+@see CCacheMemoryManager::UnlockSegments().
+*/
+TInt CCacheMemoryManager::Unlock(TUint8* aStartRamAddr, TInt aSegmentCount)
+ {
+ TInt r = iChunk.Unlock(aStartRamAddr - iBase, aSegmentCount << KSegmentSizeLog2);
+ return r;
+ }
+
+/**
+Actual implementation of LockSegments().
+@see CCacheMemoryManager::LockSegments().
+*/
+TInt CCacheMemoryManager::Lock(TUint8* aStartRamAddr, TInt aSegmentCount)
+ {
+ return iChunk.Lock(aStartRamAddr - iBase, aSegmentCount << KSegmentSizeLog2);
+ }
+
+
+//=====================================================================
+TUint8* CCacheMemoryManager::Base()
+ {
+ return iChunk.Base();
+ }
+
+/**
+Get function, returns log2 value of a segment size in bytes.
+
+@internalTechnology
+@released
+*/
+EXPORT_C TUint CCacheMemoryManager::SegmentSizeInBytesLog2() const
+ {
+ return KSegmentSizeLog2;
+ }
+
+
+//=============================================================================
+/**
+The singleton of global cache memory manager
+*/
+CCacheMemoryManager* CCacheMemoryManagerFactory::iCacheMemoryManager = NULL;
+
+/**
+Global factory function of CCacheMemoryManager.
+*/
+void CCacheMemoryManagerFactory::CreateL()
+ {
+ iCacheMemoryManager = CCacheMemoryManager::NewL(TGlobalCacheMemorySettings::CacheSize());
+ }
+
+/**
+Global get function of CCacheMemoryManager.
+
+@internalTechnology
+@released
+*/
+EXPORT_C CCacheMemoryManager* CCacheMemoryManagerFactory::CacheMemoryManager()
+ {
+ return iCacheMemoryManager;
+ }
+
+/**
+Global destroy function of CCacheMemoryManager.
+*/
+void CCacheMemoryManagerFactory::Destroy()
+ {
+ delete iCacheMemoryManager;
+ iCacheMemoryManager = NULL;
+ }
+
+//=============================================================================
+const TInt KByteToByteShift = 10;
+TInt32 TGlobalCacheMemorySettings::iCacheSizeInBytes = KDefaultGlobalCacheMemorySize << KByteToByteShift;
+TInt32 TGlobalCacheMemorySettings::iLowMemoryThreshold = KDefaultLowMemoryThreshold;
+_LIT8(KLitSectionNameCacheMemory,"CacheMemory");
+
+/**
+Read ESTART.TXT file for global cache memory settings
+*/
+void TGlobalCacheMemorySettings::ReadPropertiesFile()
+ {
+ // Get size of cache in kilobytes
+ TInt32 cacheSizeInKBytes;
+ if (F32Properties::GetInt(KLitSectionNameCacheMemory, _L8("GlobalCacheMemorySize"), cacheSizeInKBytes))
+ {
+ iCacheSizeInBytes = cacheSizeInKBytes << KByteToByteShift;
+ }
+
+ // Get low memory threshold
+ TInt32 lowMemoryThreshold;
+ if (F32Properties::GetInt(KLitSectionNameCacheMemory, _L8("LowMemoryThreshold"), lowMemoryThreshold))
+ iLowMemoryThreshold = lowMemoryThreshold;
+ }
+
+TInt TGlobalCacheMemorySettings::CacheSize()
+ {
+ return iCacheSizeInBytes;
+ }
+
+TInt TGlobalCacheMemorySettings::LowMemoryThreshold()
+ {
+ return iLowMemoryThreshold;
+ }
+
+