diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/sfile/sf_cache_client.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/sfile/sf_cache_client.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,746 @@ +// Copyright (c) 2006-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_cache_client.cpp +// +// + +/** + @file + @internalTechnology +*/ + +#include +#include +#include "sf_std.h" +#include +#include +#include +#include "sf_cache_man.h" +#include "sf_cache_client.h" +#include "sf_file_cache_defs.h" + +// This macro chnages the code so that new cachelines are stolen from the queue (if it is full) +// thus reducing the calls to RChunk::Commit +#define SYMBIAN_REUSE_STALE_CACHELINES + +enum TCacheClientFault + { + ECacheClientSegmentNotFound0, + ECacheClientSegmentNotFound1, + ECacheClientSegmentNotFound2, + ECacheClientSegmentNotFound3, + ECacheClientSegmentNotFound4, + ECacheClientSegmentNotFound5, + ECacheClientSegmentNotFound6, + ECacheClientSegmentNotFound7, + ECacheClientLruInsertFailed, + ECacheClientInsertFailed, + ECacheClientRemovingBusySegment, + ECacheClientRemovingLockedSegment, + ECacheClientRemovingDirtySegment, + ECacheClientInvalidSegmentCount, + ECacheClientAlreadyLocked, + ECacheClientSegmentNotLocked, + ECacheClientSegmentNotDirty, + ECacheClientSegmentAlreadyUnlocked, + ECacheClientSegmentBadLockCount, + ECacheClientTotalByteCountInvalid, + ECacheClientUnexpectedHole, + ECacheClientSegmentAlreadyAllocated + }; + + +LOCAL_C void Fault(TCacheClientFault aFault) +// +// Report a fault in the cache client +// + { + User::Panic(_L("FSCACHECLIENT"), aFault); + } + + +const TInt KSegmentArrayGranularity = 4; + + +//****************************** +// CCacheClient +//****************************** + +CCacheClient* CCacheClient::NewL(CCacheManager& aManager) + { + CCacheClient* client = new(ELeave) CCacheClient(aManager); + + CleanupStack::PushL(client); + client->ConstructL(); + CleanupStack::Pop(1, client); + + return client; + } + +void CCacheClient::ConstructL() + { + iCacheLines = new(ELeave) RPointerArray(KSegmentArrayGranularity); + + iLastCacheLineIndex = -1; + } + +CCacheClient::CCacheClient(CCacheManager& aManager) : iManager(aManager) + { + __CACHE_PRINT(_L("CACHECLIENT: CCacheClient()")); + + iMaxBytesCached = 0; + } + +/** +Purge() - free all cachelines +if aPurgeDirty == ETrue then discard all dirty data + E.g. if called from the destructor or following media removal +*/ +void CCacheClient::Purge(TBool aPurgeDirty) + { + TInt cacheLineCount = iCacheLines->Count(); + TInt n; + for (n=0; nClose(); + } + + delete iCacheLines; + } + +void CCacheClient::SetMaxSegments(TInt aMaxSegments) + { + iMaxBytesCached = aMaxSegments << iManager.SegmentSizeLog2(); + } + + +TInt CCacheClient::SegmentSize() + { + return iManager.SegmentSize(); + } + +TInt CCacheClient::SegmentSizeLog2() + { + return iManager.SegmentSizeLog2(); + } + +TInt64 CCacheClient::SegmentSizeMask() + { + return iManager.SegmentSizeMask(); + } + +TInt CCacheClient::CacheLineSize() + { + return iManager.CacheLineSize(); + } + +TInt CCacheClient::CacheLineSizeInSegments() + { + return iManager.CacheLineSizeInSegments(); + } + +TUint8* CCacheClient::FindAndLockSegments(TInt64 aPos, TInt& aSegmentCount, TInt& aFilledSegmentCount, TInt& aLockError, TBool aMakeDirty) + { + TInt maxSegments = Min(aSegmentCount, CacheLineSizeInSegments()); + aSegmentCount = 0; + aFilledSegmentCount = 0; + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + aLockError = KErrNone; + + if (!cacheLine) + return NULL; + + TInt offset = (TInt) (aPos - cacheLine->iPos); + TInt len = CacheLineLen(cacheLine) - offset; + + TInt segmentSizeLog2 = iManager.SegmentSizeLog2(); + + TInt startSegmentNumber = offset >> segmentSizeLog2; + TInt filledCount = iManager.FillCount(this, *cacheLine); + + // round up to a whole number of segments + aSegmentCount = ((len + iManager.SegmentSize() - 1) >> segmentSizeLog2); + aSegmentCount = Min(aSegmentCount, maxSegments); + + // get filled count + aFilledSegmentCount = (filledCount > startSegmentNumber)?filledCount - startSegmentNumber:0; + + __CACHE_PRINT4(_L("CACHECLIENT: FindAndLockSegments(), Client %08X pos %d addr %08X len %d"), + this, I64LOW(cacheLine->iPos), cacheLine->iAddr, CacheLineLen(cacheLine)); + + + aLockError = LockSegments(aPos, aSegmentCount, aMakeDirty); + if (aLockError != KErrNone) + return NULL; + + return cacheLine->iAddr + offset; + } + +TUint8* CCacheClient::FindSegment(TInt64 aPos) + { + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + if (!cacheLine) + return NULL; + + TInt offset = (TInt) (aPos - cacheLine->iPos); + return cacheLine->iAddr + offset; + } + +TUint8* CCacheClient::AllocateAndLockSegments(TInt64 aPos, TInt& aSegmentCount, TBool aMakeDirty, TBool aExtendExisting) + { + __ASSERT_DEBUG(aSegmentCount >= 0, Fault(ECacheClientInvalidSegmentCount)); + + TInt segmentSizeLog2 = iManager.SegmentSizeLog2(); + TInt segmentSize = iManager.SegmentSize(); + TInt cacheLineSize = iManager.CacheLineSize(); + + aPos = (aPos >> segmentSizeLog2) << segmentSizeLog2; + + + // count number of uncached segments + TInt maxSegments = Min(aSegmentCount, CacheLineSizeInSegments()); + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + // This is test code and changes the behaviour so that we always allocate + // as large a cacheline as possible, so as to increase the likelihood of "holes" + if (iManager.AllocateMaxSegments()) + { + maxSegments = cacheLineSize >> segmentSizeLog2; + } +#endif + + // make sure requested range doesn't overlap with an existing cacheline - + // if it does, shrink requested length down + TInt64 endPos = aPos + (maxSegments << segmentSizeLog2); + TInt cacheLineCount = iCacheLines->Count(); + for (TInt index=0; index < cacheLineCount; index++) + { + const CCacheManager::TCacheLine* cacheLine = (*iCacheLines)[index]; + TInt64 startPos = cacheLine->iPos; + if (cacheLine->iClient == this && startPos >= aPos && startPos < endPos) + { + endPos = cacheLine->iPos; + } + } + TInt segmentCount = (TInt) ((endPos - aPos) >> segmentSizeLog2); + + __ASSERT_DEBUG(segmentCount > 0, Fault(ECacheClientSegmentAlreadyAllocated)); + + aSegmentCount = Min(segmentCount, aSegmentCount); + + iLastCacheLineIndex = -1; + + TUint8* segmentAddr = NULL; + + __CACHE_PRINT2(_L("CACHECLIENT: AllocateAndLockSegments(%ld, %d)"), aPos, segmentCount); + + // can we extend an existing cacheline ? (this saves wasting virtual memory) + // NB if we're about the make the new segment(s) dirty, only extend if last segment in existing + // cacheline is dirty, otherwise we'll end up unnecessarily marking lots of clean segments as dirty + if (aExtendExisting) + { + TInt64 posLastSegment = aPos - segmentSize; + const CCacheManager::TCacheLine* cacheLineOld; + TInt r; + if ((posLastSegment >= 0) && ((cacheLineOld = FindCacheLine(posLastSegment)) != NULL)) + { + TInt prevSegmentNumber = StartSegment(cacheLineOld, posLastSegment); + TInt fillCountOld = iManager.FillCount(this, *cacheLineOld); + TInt fillCountNew = segmentCount + prevSegmentNumber+1; // fillCountOld; + if (prevSegmentNumber+1 == fillCountOld && + fillCountNew <= (cacheLineSize >> segmentSizeLog2) && + (!aMakeDirty || (prevSegmentNumber+1 == cacheLineOld->iDirtySegments)) + ) + { + __CACHE_PRINT(_L("CACHE: extending cacheline")); + + segmentAddr = cacheLineOld->iAddr + (TInt) (aPos - cacheLineOld->iPos); + + // Lock the cacheline and then try to extend it + r = LockSegments(cacheLineOld->iPos, cacheLineOld->iAllocatedSegments, ETrue); + if (r == KErrNone) + { + r = iManager.ExtendCacheLine(this, *cacheLineOld, fillCountNew); +//RDebug::Print(_L("GROW addr %08X, prevSegmentNumber %d, fillCount %d, fillCountNew %d, r %d\n"), +// cacheLineOld->iAddr, prevSegmentNumber, fillCountOld, fillCountNew, r); + if (r == KErrNone) + { + // If we've exceeded max, use LRU queue to discard old cachelines + RemoveLru(cacheLineOld); + return segmentAddr; + } + __CACHE_PRINT(_L("LockSegments FAIL")); + UnlockSegments(posLastSegment); + } + } + } + } + + // reserve space in the segment array & LRU queue so we don't have to + // worry about failing to append + if (iCacheLines->Reserve(1) != KErrNone) + return NULL; + + const CCacheManager::TCacheLine* cacheLineNew = NULL; + TBool reUsedCacheLineGrown = EFalse; + +#ifdef SYMBIAN_REUSE_STALE_CACHELINES + // try to re-use an old cacheline if possible to avoid having to commit a new one + // as this involves calling RChunk::Commit() which takes some time.... + TInt lenNewCacheLine = segmentCount << segmentSizeLog2; + TInt totalBytesCached = CachedBytes() + lenNewCacheLine; + + cacheLineCount = iCacheLines->Count(); + if (cacheLineCount > 0) + { + const CCacheManager::TCacheLine* cacheLineOld = (*iCacheLines)[cacheLineCount - 1]; + TInt lenOldCacheLine = cacheLineOld->iFilledSegments << segmentSizeLog2; + reUsedCacheLineGrown = segmentCount > cacheLineOld->iAllocatedSegments; + if (totalBytesCached + lenNewCacheLine - lenOldCacheLine > iMaxBytesCached && + cacheLineOld->iClient == this && + cacheLineOld->iLockCount == 0) + { + if (iManager.ReAllocateAndLockCacheLine(this, aPos, *cacheLineOld, segmentCount) == KErrNone) + { + cacheLineNew = cacheLineOld; + } + } + } +#endif // SYMBIAN_REUSE_STALE_CACHELINES + TBool reUsingCacheline = cacheLineNew ? (TBool)ETrue:(TBool)EFalse; + + // Request a free segment from cache manager + if (reUsingCacheline) + { + iCacheLines->Remove(cacheLineCount-1); + } + else + { + TInt r = iManager.AllocateAndLockCacheLine(this, aPos, cacheLineNew, segmentCount); + if (r != KErrNone) + { + __CACHE_PRINT1(_L("CACHECLIENT: AllocateSegment() failed r %d"), r); + return NULL; + } + // check the address isn't already in the iCacheLines - + // this can happen if it was stolen from us and we then steal it back + TInt indexDup = iCacheLines->Find(cacheLineNew); + if (indexDup != KErrNotFound) + iCacheLines->Remove(indexDup); + } + + + segmentAddr = cacheLineNew->iAddr; + + // Add to top of LRU queue + TInt r = iCacheLines->Insert(cacheLineNew, 0); + __ASSERT_ALWAYS(r == KErrNone, Fault(ECacheClientInsertFailed)); + + __CACHE_PRINT4(_L("CACHECLIENT: AllocateAndLockSegments(), Client %08X pos %d addr %08X len %d"), + this, I64LOW(cacheLineNew->iPos), cacheLineNew->iAddr, CacheLineLen(cacheLineNew)); + + // assume LRU in use ... + iLastCacheLineIndex = 0; + + if (!reUsingCacheline || reUsedCacheLineGrown) + RemoveLru(cacheLineNew); + + return segmentAddr; + } + + + +TInt CCacheClient::StartSegment(const CCacheManager::TCacheLine* aCacheLine, TInt64 aPos) + { + TInt offset = (TInt) (aPos - aCacheLine->iPos); + return offset >> iManager.SegmentSizeLog2(); + } + +TInt CCacheClient::CacheLineLen(const CCacheManager::TCacheLine* aCacheLine) + { + return aCacheLine->iAllocatedSegments << iManager.SegmentSizeLog2(); + } + + +void CCacheClient::MarkSegmentsAsFilled(TInt64 aPos, TInt aSegmentCount) + { + __CACHE_PRINT2(_L("CACHECLIENT: Mark Filled Segments(%ld, %d)"), aPos, aSegmentCount); + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound0)); + + iManager.SetFilled(this, *cacheLine, StartSegment(cacheLine, aPos) + aSegmentCount); + } + +void CCacheClient::MarkSegmentsAsDirty(TInt64 aPos, TInt aSegmentCount) + { + __CACHE_PRINT2(_L("CACHECLIENT: Mark Dirty Segments(%ld, %d)"), aPos, aSegmentCount); + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound1)); + + iManager.SetDirty(this, *cacheLine, StartSegment(cacheLine, aPos) + aSegmentCount); + } + +TInt CCacheClient::FindFirstDirtySegment(TInt64& aPos, TUint8*& aAddr) + { + TInt cacheLineCount = iCacheLines->Count(); + + aPos = KMaxTInt64; + TInt segmentCount = 0; + for (TInt index = 0; index< cacheLineCount; index++) + { + CCacheManager::TCacheLine& cacheLine = *(*iCacheLines)[index]; + + TInt dirtyCount = iManager.DirtyCount(this, cacheLine); + if ((dirtyCount > 0 && cacheLine.iPos < aPos)) + { + aPos = cacheLine.iPos; + aAddr = cacheLine.iAddr; + segmentCount = dirtyCount; + } + } + + return segmentCount; + } + + +void CCacheClient::MarkSegmentsAsClean(TInt64 aPos) + { + __CACHE_PRINT1(_L("CACHECLIENT: MarkSegmentsAsClean(%d)"), I64LOW(aPos)); + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound2)); + + // this sets the dirty count to zero, unlocks the cacheline and + // marks all the dirty pages as filled + iManager.ClearDirty(this, *cacheLine); + + RemoveLru(cacheLine); + } + + +void CCacheClient::RemoveEmptySegments(const CCacheManager::TCacheLine* aCacheLine) + { + iManager.RemoveEmptySegments(this, *aCacheLine); + } + +TInt CCacheClient::LockSegments(TInt64 aPos, TInt aSegmentCount, TBool aMakeDirty) + { + __CACHE_PRINT1(_L("CACHECLIENT: LockCacheLine(%d, %d)"), I64LOW(aPos)); + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound3)); + + + TInt startSegmentNumber = StartSegment(cacheLine, aPos); + + TInt lockError; + if (aMakeDirty) + lockError = iManager.LockCacheLine(this, *cacheLine, 0, cacheLine->iAllocatedSegments); + else + lockError = iManager.LockCacheLine(this, *cacheLine, startSegmentNumber, aSegmentCount); + + if (lockError == KErrInUse) + { + return lockError; + } + else if (lockError != KErrNone) + { + RemoveCacheLine(cacheLine); + return lockError; + } + + // Check for "holes".i.e. empty segments before this one. + // If found, discard the empty segments and return KErrNotFound + TInt filledCount = iManager.FillCount(this, *cacheLine); + if (startSegmentNumber > filledCount) + { + __CACHE_PRINT(_L("CACHE: found hole")); +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) + iManager.Stats().iHoleCount++; +#endif + + + RemoveEmptySegments(cacheLine); + iManager.UnlockCacheLine(this, *cacheLine); + if (CacheLineLen(cacheLine) == 0) + FreeCacheLine(cacheLine); + return KErrNotFound; + } + + // Move this entry to top of LRU queue + iCacheLines->Remove(iLastCacheLineIndex); +#ifdef _DEBUG + TInt r = +#endif + iCacheLines->Insert(cacheLine, 0); + __ASSERT_DEBUG(r == KErrNone, Fault(ECacheClientLruInsertFailed)); + iLastCacheLineIndex = 0; + + + return KErrNone; + } + + +/** +UnlockSegments() +*/ +void CCacheClient::UnlockSegments(TInt64 aPos) + { + __CACHE_PRINT1(_L("CACHECLIENT: UnlockSegments(%d, %d)"), I64LOW(aPos)); + + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound4)); + + iManager.UnlockCacheLine(this, *cacheLine); + } + + +TInt CCacheClient::FindCacheLineIndex(TInt64 aPos) + { + TInt cacheLineCount = iCacheLines->Count(); + + if (iLastCacheLineIndex != -1 && iLastCacheLineIndex < cacheLineCount) + { + const CCacheManager::TCacheLine* cacheLine = (*iCacheLines)[iLastCacheLineIndex]; + + if (cacheLine->iClient == this && + aPos >= cacheLine->iPos && + aPos < cacheLine->iPos+CacheLineLen(cacheLine)) + return iLastCacheLineIndex; + } + + for (TInt index=0; index < cacheLineCount; index++) + { + const CCacheManager::TCacheLine* cacheLine = (*iCacheLines)[index]; + + if (cacheLine->iClient == this && + aPos >= cacheLine->iPos && + (aPos < cacheLine->iPos+CacheLineLen(cacheLine))) + { + iLastCacheLineIndex = index; + return index; + } + } + + return KErrNotFound; + } + +const CCacheManager::TCacheLine* CCacheClient::FindCacheLine(TInt64 aPos) + { + TInt index = FindCacheLineIndex(aPos); + + return (index == KErrNotFound) ? NULL : (*iCacheLines)[index]; + } + + +TBool CCacheClient::SegmentEmpty(TInt64 aPos) + { + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound5)); + + TInt startSegment = StartSegment(cacheLine, aPos); + TInt fillCount = iManager.FillCount(this, *cacheLine); + + + return startSegment >= fillCount ? (TBool)ETrue : (TBool)EFalse; + } + + +TBool CCacheClient::SegmentDirty(TInt64 aPos) + { + const CCacheManager::TCacheLine* cacheLine = FindCacheLine(aPos); + + __ASSERT_ALWAYS(cacheLine != NULL, Fault(ECacheClientSegmentNotFound6)); + + TInt startSegment = StartSegment(cacheLine, aPos); + TInt dirtyCount = iManager.DirtyCount(this, *cacheLine); + + return startSegment >= dirtyCount ? (TBool)ETrue : (TBool)EFalse; + } + +// return whether there are too many locked pages globally (for all files) +// or too many for this file +TBool CCacheClient::TooManyLockedSegments() + { + if (iManager.TooManyLockedSegments()) + return ETrue; + if (LockedBytes() > iMaxBytesCached) + return ETrue; + return EFalse; + } + + +TInt CCacheClient::CachedBytes() + { + TInt cacheLineCount = iCacheLines->Count(); + + TInt totalBytesCached = 0; + for (TInt n=0; n < cacheLineCount; n++) + totalBytesCached+= ((*iCacheLines)[n]->iFilledSegments << iManager.SegmentSizeLog2()); + return totalBytesCached; + } + +TInt CCacheClient::LockedBytes() + { + TInt cacheLineCount = iCacheLines->Count(); + TInt segmentSizeLog2 = iManager.SegmentSizeLog2(); + + TInt totalBytesLocked = 0; + for (TInt n=0; n < cacheLineCount; n++) + { + CCacheManager::TCacheLine& cacheLine = *(*iCacheLines)[n]; + if (cacheLine.iLockCount > 0) + totalBytesLocked+= cacheLine.iAllocatedSegments << segmentSizeLog2; + } + return totalBytesLocked; + } + +void CCacheClient::RemoveLru(const CCacheManager::TCacheLine* aCacheLineToExclude) + { + if (iMaxBytesCached == 0) // LRU queue ? + return; + + // If we've exceeded max, use LRU queue to remove stuff + + TInt cacheLineCount = iCacheLines->Count(); + TInt segmentSizeLog2 = iManager.SegmentSizeLog2(); + + // calculate the total bytes cached in all cachelines we own + // NB it's difficult to keep a track of this in this class because cachelines can be stolen (!) + TInt totalBytesCached = CachedBytes(); + for (TInt lastIndex = cacheLineCount - 1; + lastIndex >= 0 && totalBytesCached > iMaxBytesCached; + lastIndex--) + { + const CCacheManager::TCacheLine* cacheLine = (*iCacheLines)[lastIndex]; + +// __CACHE_PRINT3(_L("Test cacheline index %d pos %ld len %d"), lastIndex, cacheLine.iPos, cacheLine.iLen); + + if (cacheLine != aCacheLineToExclude) + { + // if removing a cacheline will bring the total to UNDER the "maximum" + // then don't remove it and abort - to do otherwise could remove + // data that has just been read-ahead .... + TInt lenCacheLine = cacheLine->iFilledSegments << segmentSizeLog2; + if (totalBytesCached - lenCacheLine <= iMaxBytesCached) + { + __CACHE_PRINT(_L("CACHECLIENT: cacheline too big to remove, aborting..")); + break; + } + + __CACHE_PRINT3(_L("CACHECLIENT: Removing LRU index %d pos %ld len %d"), lastIndex, cacheLine->iPos, CacheLineLen(cacheLine)); + TInt bytesFreed = cacheLine->iFilledSegments << iManager.SegmentSizeLog2(); + if (FreeCacheLine(cacheLine)) + { + totalBytesCached-= bytesFreed; + __ASSERT_ALWAYS(totalBytesCached >= 0, Fault(ECacheClientTotalByteCountInvalid)); + } + } + } + } + + + +TBool CCacheClient::FreeCacheLine(const CCacheManager::TCacheLine* aCacheLine) + { + __CACHE_PRINT1(_L("CACHECLIENT: FreeCacheLine(%d) )"), I64LOW(aCacheLine->iPos)); + + + TBool success = iManager.FreeCacheLine(this, *aCacheLine); + + if (success) + RemoveCacheLine(aCacheLine); + + return success; + } + +void CCacheClient::RemoveCacheLine(const CCacheManager::TCacheLine* aCacheLine) + { + __CACHE_PRINT1(_L("CACHECLIENT: RemoveCacheLine(%d) )"), I64LOW(aCacheLine->iPos)); + + TInt index = iCacheLines->Find(aCacheLine); + + __ASSERT_ALWAYS(index != KErrNotFound, Fault(ECacheClientSegmentNotFound7)); + + iCacheLines->Remove(index); + } + +#if defined(_DEBUG) || defined(_DEBUG_RELEASE) +void CCacheClient::DumpCache() + { + RDebug::Print(_L("**** CACHECLIENT: CacheLines ****\n")); + TInt cacheLineCount = iCacheLines->Count(); + + for (TInt index = 0; index< cacheLineCount; index++) + { + CCacheManager::TCacheLine& cacheLine = *(*iCacheLines)[index]; + iManager.DumpCacheLine(cacheLine); + } + } +#endif