userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp
changeset 201 43365a9b78a3
parent 102 ef2a444a7410
equal deleted inserted replaced
200:73ea206103e6 201:43365a9b78a3
   111                  :iPageSizeLog2(aPageSizeInBytesLog2),
   111                  :iPageSizeLog2(aPageSizeInBytesLog2),
   112                   iWrGranularityLog2(aWrGranularityLog2),
   112                   iWrGranularityLog2(aWrGranularityLog2),
   113                   iMinSizeInPages(aMinPageNum),
   113                   iMinSizeInPages(aMinPageNum),
   114                   iMaxSizeInPages(aMaxPageNum),
   114                   iMaxSizeInPages(aMaxPageNum),
   115                   iDrive(aDrive),
   115                   iDrive(aDrive),
       
   116 				  iLastVisitedPage(NULL),
   116                   iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   117                   iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   117                   iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   118                   iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   118                   iLockedQCount(0),
   119                   iLockedQCount(0),
   119                   iUnlockedQCount(0),
   120                   iUnlockedQCount(0),
   120                   iHashFunction(HashFunction),
   121                   iHashFunction(HashFunction),
   156 		}
   157 		}
   157 
   158 
   158 
   159 
   159 	// allocate as many permanently locked pages as there are threads - plus one
   160 	// allocate as many permanently locked pages as there are threads - plus one
   160 	// otherwise DoMakePageMRU() won't work properly with only one thread
   161 	// otherwise DoMakePageMRU() won't work properly with only one thread
   161 	//-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool)
   162     //-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool)
   162 	const TUint KThreadCount = 1;
   163     const TUint KThreadCount = 1;
   163 	iPermanentlyAllocatedPageCount = KThreadCount + 1; 
   164     iPermanentlyAllocatedPageCount = KThreadCount; 
   164 
   165 
   165 	if (iPermanentlyAllocatedPageCount > iMinSizeInPages)
   166 	if (iPermanentlyAllocatedPageCount > iMinSizeInPages)
   166 		iMinSizeInPages = iPermanentlyAllocatedPageCount;
   167 		iMinSizeInPages = iPermanentlyAllocatedPageCount;
   167 
   168 
   168 	for (TUint n=0; n<iPermanentlyAllocatedPageCount; n++)
   169 	for (TUint n=0; n<iPermanentlyAllocatedPageCount; n++)
   169 		{
   170 		{
   170 		TDynamicDirCachePage* pPage = AllocateAndLockNewPage(0);
   171         TDynamicDirCachePage* pPage = AllocateAndLockNewPage();
   171 		ASSERT(pPage);
   172         ASSERT(pPage);
   172 		if (!pPage)
   173         if (!pPage)
   173 			User::Leave(KErrNoMemory);
   174             User::Leave(KErrNoMemory);
   174 		AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked);
   175 		AddFirstOntoQueue(pPage, TDynamicDirCachePage::ELocked);
   175 		LookupTblAdd(pPage);
   176 		LookupTblAdd(pPage);
   176 		}
   177 		}
   177 
   178 
   178 	}
   179 	}
   189     CleanupStack::Pop();
   190     CleanupStack::Pop();
   190     return pSelf;
   191     return pSelf;
   191     }
   192     }
   192 
   193 
   193 /**
   194 /**
   194 Insert an unlocked page into the last position of the locked queue, may squeeze the original last page into
       
   195 the unlocked queue.
       
   196 This function is used on last visited but 'unlocked' pages to avoid excessive lock/unlock calls to cache memory
       
   197 manager as contiguous entry reading/writing often happens on the same page.
       
   198 @param	aPage	the page to be inserted.
       
   199 @pre	the page type of aPage should only be TDynamicDirCachePage::EUnknown
       
   200 */
       
   201 void CDynamicDirCache::MakePageLastLocked(TDynamicDirCachePage* aPage)
       
   202 	{
       
   203 	// this function should not be called on active pages
       
   204 	ASSERT(aPage->iType == TDynamicDirCachePage::EUnknown);
       
   205 
       
   206 	if (iLockedQ.IsEmpty())
       
   207 		{
       
   208 		// if locked queue is empty, add it onto the locked queue directly
       
   209 		AddFirstOntoQueue(aPage, TDynamicDirCachePage::ELocked);
       
   210 		}
       
   211 	else
       
   212 		{
       
   213 		// otherwise, we squeeze for the last position on locked queue
       
   214 		while (iLockedQCount + 1 >= iMinSizeInPages)
       
   215 			{
       
   216 			TDynamicDirCachePage* last = iLockedQ.Last();
       
   217 			DeQueue(last);
       
   218 			UnlockPage(last);
       
   219 			AddFirstOntoQueue(last, TDynamicDirCachePage::EUnlocked);
       
   220 			}
       
   221 
       
   222 		// iLockedQCount + 1 < iMinSizeInPages
       
   223 		iLockedQ.AddLast(*aPage);
       
   224 		aPage->SetPageType(TDynamicDirCachePage::ELocked);
       
   225 		iLockedQCount++;
       
   226 		}
       
   227 	}
       
   228 
       
   229 /**
       
   230     Read data from a single page. If the page is not found or not valid anymore, read media onto iActive page first.
   195     Read data from a single page. If the page is not found or not valid anymore, read media onto iActive page first.
   231     The data will be _Appended_ the the descriptor aDes. The caller is responsible for maintaining this descriptor.
   196     The data will be _Appended_ the the descriptor aDes. The caller is responsible for maintaining this descriptor.
   232 
   197 
   233     @param	aPos	the starting position of the media address to be read.
   198     @param	aPos	the starting position of the media address to be read.
   234     @param	aLength	the length of the content to be read.
   199     @param	aLength	the length of the content to be read.
   246     		{
   211     		{
   247     		// read data and append them to the descriptor
   212     		// read data and append them to the descriptor
   248             aDes.Append(pPage->PtrInPage(aPos), aLength);
   213             aDes.Append(pPage->PtrInPage(aPos), aLength);
   249 
   214 
   250 
   215 
   251             // if page is from unlocked queue, insert it onto the last page of the locked
   216             // if page is from unlocked queue, try to keep it locked until we move to a 
   252             //  queue. this is to avoid excessive locking and unlocking operations that is
   217             //  different page from the unlocked queue 
   253             //  highly likely to happen for following reads.
   218             // this is to avoid excessive locking and unlocking operations that is
   254             if (pPage->PageType() == TDynamicDirCachePage::EUnlocked)
   219             //  highly likely to happen when DoFindL() linearly scan through the directory
   255             	{
   220             if (pPage->PageType() == TDynamicDirCachePage::EUnlocked
   256             	DeQueue(pPage);
   221                 && iLastVisitedPage != pPage)
   257             	MakePageLastLocked(pPage);
   222                 {
       
   223                 // Note: iLastVisitedPage may have been moved from unlocked queue to locked queue
       
   224                 if(iLastVisitedPage && iLastVisitedPage->PageType() == TDynamicDirCachePage::EUnlocked)
       
   225                     {
       
   226                     User::LeaveIfError(UnlockPage(iLastVisitedPage));
       
   227                     }
       
   228                 iLastVisitedPage = pPage;
   258             	}
   229             	}
   259     		}
   230     		}
   260     	else	// page locking failed
   231     	else	// page locking failed
   261     		{
   232     		{
   262     		ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked);
   233     		ASSERT(pPage->PageType() == TDynamicDirCachePage::EUnlocked);
   622 
   593 
   623         // dump cache, for debug
   594         // dump cache, for debug
   624         case EDumpCache:
   595         case EDumpCache:
   625         	{
   596         	{
   626         	RFs fs;
   597         	RFs fs;
   627         	fs.Connect();
   598         	r = fs.Connect();
       
   599             if(r != KErrNone)
       
   600                 break;
       
   601 
   628         	const TUint32 debugRegister = DebugRegister();
   602         	const TUint32 debugRegister = DebugRegister();
   629         	fs.SetDebugRegister(debugRegister|KFSYS);
   603         	fs.SetDebugRegister(debugRegister|KFSYS);
   630         	Dump();
   604         	Dump();
   631         	fs.SetDebugRegister(debugRegister);
   605         	fs.SetDebugRegister(debugRegister);
   632         	fs.Close();
   606         	fs.Close();
       
   607         	r = KErrNone;
   633         	break;
   608         	break;
   634         	}
   609         	}
   635         case ECacheInfo:
   610         case ECacheInfo:
   636         	{
   611         	{
   637         	RFs fs;
   612         	RFs fs;
   638         	fs.Connect();
   613         	r = fs.Connect();
       
   614             if(r != KErrNone)
       
   615                 break;
       
   616         	
   639         	const TUint32 debugRegister = DebugRegister();
   617         	const TUint32 debugRegister = DebugRegister();
   640         	fs.SetDebugRegister(debugRegister|KFSYS);
   618         	fs.SetDebugRegister(debugRegister|KFSYS);
   641         	Info();
   619             TDirCacheInfo* aInfo = static_cast<TDirCacheInfo*>(aParam2);
       
   620             Info(aInfo);
   642         	fs.SetDebugRegister(debugRegister);
   621         	fs.SetDebugRegister(debugRegister);
   643         	fs.Close();
   622         	fs.Close();
       
   623         	r = KErrNone;
   644         	break;
   624         	break;
   645         	}
   625         	}
   646 
   626 
   647         default:
   627         default:
   648             __PRINT1(_L("CDynamicDirCache::Control() invalid function: %d"), aFunction);
   628             __PRINT1(_L("CDynamicDirCache::Control() invalid function: %d"), aFunction);
   681 
   661 
   682 void CDynamicDirCache::DoMakePageMRU(TInt64 aPos)
   662 void CDynamicDirCache::DoMakePageMRU(TInt64 aPos)
   683 	{
   663 	{
   684 //	__PRINT1(_L("MakePageMRU (%lx)"), aPos);
   664 //	__PRINT1(_L("MakePageMRU (%lx)"), aPos);
   685 //	__PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages);
   665 //	__PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages);
   686 	// check there are at least two locked pages
   666 	// check there are at least one locked pages
   687 	ASSERT(iLockedQCount > 1);
   667 	ASSERT(iLockedQCount > 0);
   688 	
   668 	
   689 	// check the MRU page first, if it is already the MRU page, we can return immediately
   669 	// check the MRU page first, if it is already the MRU page, we can return immediately
   690 	TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   670 	TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   691 	if (!iLockedQ.IsEmpty())
   671 	if (!iLockedQ.IsEmpty())
   692 		{
   672 		{
   693 		if (iLockedQ.First()->StartPos() == pageStartMedPos)
   673         if (iLockedQCount > 1 && iLockedQ.First()->StartPos() == pageStartMedPos)
   694 			{
   674 			{
   695 			return;
   675 			return;
   696 			}
   676 			}
   697 		}
   677 		}
   698 
   678 
   701 		{
   681 		{
   702 		ASSERT(pPage->IsValid());
   682 		ASSERT(pPage->IsValid());
   703 		// lock page before make it MRU
   683 		// lock page before make it MRU
   704 		if (pPage->PageType() == TDynamicDirCachePage::EUnlocked)
   684 		if (pPage->PageType() == TDynamicDirCachePage::EUnlocked)
   705 			{
   685 			{
   706 			ASSERT(!pPage->IsLocked());
   686             ASSERT(!pPage->IsLocked() || (pPage->IsLocked() && pPage == iLastVisitedPage));
   707 			if (LockPage(pPage) == NULL)
   687 			if (LockPage(pPage) == NULL)
   708 				{
   688 				{
   709 				DeQueue(pPage);
   689 				DeQueue(pPage);
   710 				LookupTblRemove(pPage->StartPos());
   690 				LookupTblRemove(pPage->StartPos());
   711 				DecommitPage(pPage);
   691 				DecommitPage(pPage);
   733 
   713 
   734 	// by now, the page is either locked or active page
   714 	// by now, the page is either locked or active page
   735 	ASSERT(pPage && pPage->IsValid() && pPage->IsLocked());
   715 	ASSERT(pPage && pPage->IsValid() && pPage->IsLocked());
   736 
   716 
   737 
   717 
   738 	// if we used the active page (last on the queue), try to grow the cache.
   718 
   739 	TBool growCache = pPage == iLockedQ.Last();
   719     TBool makeNewPageMRU = pPage == iLockedQ.Last();
       
   720 
   740 
   721 
   741 	switch (pPage->PageType())
   722 	switch (pPage->PageType())
   742 		{
   723 		{
   743 		case TDynamicDirCachePage::EUnlocked:
   724 		case TDynamicDirCachePage::EUnlocked:
   744 			{
   725 			{
   762 			}
   743 			}
   763 		default:
   744 		default:
   764 			ASSERT(0);
   745 			ASSERT(0);
   765 		}
   746 		}
   766 
   747 
   767 	if (CacheIsFull() || !growCache)
   748     if (!makeNewPageMRU)
   768 		return;
   749         return;
   769 
   750     
   770 	// attempt to grow the cache by appending a clean, new page at the end of the LRU list.
   751     // when cache is full and a new MRU page is about to be added, we will need to evict the LRU page
   771 	// This can fail when out of memory; the LRU mechanism then makes sure the oldest page will be re-used.
   752     //  accordingly
   772 	TDynamicDirCachePage* nPage = AllocateAndLockNewPage(0);
   753     if (CacheIsFull())
   773 	if (!nPage)
   754         {
   774 		return;
   755         TUint32& queueCnt = iMaxSizeInPages - iMinSizeInPages > 0 ? iUnlockedQCount : iLockedQCount;
   775 
   756         queueCnt++;
   776 	// about to add a page to end of locked queue, so lie about iLockedQCount
   757         CheckThresholds();
       
   758         queueCnt--;
       
   759         }
       
   760 
       
   761     // attempt to grow the cache by appending a clean, new page at the end of the locked page queue.
       
   762     // This can fail when out of memory; the LRU mechanism then makes sure the oldest page will be re-used.
       
   763     TDynamicDirCachePage* nPage = AllocateAndLockNewPage();
       
   764     if (!nPage)
       
   765         return;
       
   766 
       
   767     // about to add the new active page, force the locked queue to evict the existing last page to make room 
       
   768     //  for the new active page 
   777 	iLockedQCount++;
   769 	iLockedQCount++;
   778 	CheckThresholds();
   770 	CheckThresholds();
   779 	iLockedQCount--;
   771 	iLockedQCount--;
   780 
   772 
   781 	iLockedQ.AddLast(*nPage);
   773 	iLockedQ.AddLast(*nPage);
   782 	nPage->SetPageType(TDynamicDirCachePage::ELocked);
   774 	nPage->SetPageType(TDynamicDirCachePage::ELocked);
   783 	++iLockedQCount;
   775 	++iLockedQCount;
   784 	LookupTblAdd(nPage);
       
   785 	}
   776 	}
   786 
   777 
   787 /**
   778 /**
   788     Implementation of pure virtual function.
   779     Implementation of pure virtual function.
   789     @see	MDiskSpecialAccessor::MakePageMRU()
   780     @see	MDiskSpecialAccessor::MakePageMRU()
   855 Check if the number of (locked pages + iActive page) and unlocked pages have exceeded minimum allowed page
   846 Check if the number of (locked pages + iActive page) and unlocked pages have exceeded minimum allowed page
   856 number and maximum allowed page number respectively.
   847 number and maximum allowed page number respectively.
   857 */
   848 */
   858 void CDynamicDirCache::CheckThresholds()
   849 void CDynamicDirCache::CheckThresholds()
   859 	{
   850 	{
   860 	while (iLockedQCount + 1 > iMinSizeInPages)
   851     while (iLockedQCount > iMinSizeInPages)
   861 		{
   852 		{
   862 		TDynamicDirCachePage* movePage = iLockedQ.Last();
   853 		TDynamicDirCachePage* movePage = iLockedQ.Last();
   863 		UnlockPage(movePage);
   854 		UnlockPage(movePage);
   864 		DeQueue(movePage);
   855 		DeQueue(movePage);
   865 		TInt err = LookupTblRemove(movePage->StartPos());
   856 		TInt err = LookupTblRemove(movePage->StartPos());
   895 
   886 
   896 /**
   887 /**
   897 Try to create a new page and lock the page content when it is created. This function should only be called
   888 Try to create a new page and lock the page content when it is created. This function should only be called
   898 when creating iActive page or making a page MRU (which might result in page evictions).
   889 when creating iActive page or making a page MRU (which might result in page evictions).
   899 @return	the pointer of the newly created page, or NULL if allocation failed.
   890 @return	the pointer of the newly created page, or NULL if allocation failed.
   900 @param	aStartMedPos	the starting media address of the page to be created.
   891 */
   901 @pre	aStartMedPos should not already be existing in the cache.
   892 TDynamicDirCachePage* CDynamicDirCache::AllocateAndLockNewPage(/*TInt64 aStartMedPos*/)
   902 */
   893     {
   903 TDynamicDirCachePage* CDynamicDirCache::AllocateAndLockNewPage(TInt64 aStartMedPos)
   894     __PRINT(_L("CDynamicDirCache::AllocateAndLockNewPage()"));
   904 	{
   895 
   905 	__PRINT1(_L("CDynamicDirCache::AllocateAndLockNewPage(aStartMedPos=%lx)"), aStartMedPos);
   896     TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs());
   906 
   897 
   907 	TUint8* startRamAddr = iCacheMemoryClient->AllocateAndLockSegments(PageSizeInSegs());
   898     if (!startRamAddr)
   908 
   899         return NULL;
   909 	if (!startRamAddr)
   900 
   910 		return NULL;
   901     TDynamicDirCachePage* pPage = TDynamicDirCachePage::CreateCachePage(this, 0, startRamAddr);
   911 
   902 
   912 	TDynamicDirCachePage* pPage = TDynamicDirCachePage::CreateCachePage(this, aStartMedPos, startRamAddr);
   903     // Failure would mean the cache chunk was able to grow but we've run out of heap.
   913 
   904     // This seems extremely unlikely, but decommit the now-unmanageable cache segment just in case.
   914 	// Failure would mean the cache chunk was able to grow but we've run out of heap.
   905     if (!pPage)
   915 	// This seems extremely unlikely, but decommit the now-unmanageable cache segment just in case.
   906         {
   916 	if (!pPage)
   907         iCacheMemoryClient->DecommitSegments(startRamAddr, PageSizeInSegs());
   917 		{
   908         return NULL;
   918 		iCacheMemoryClient->DecommitSegments(startRamAddr, PageSizeInSegs());
   909         }
   919 		return NULL;
       
   920 		}
       
   921 
   910 
   922 	pPage->SetLocked(ETrue);
   911 	pPage->SetLocked(ETrue);
   923 	pPage->SetValid(EFalse);
   912 	pPage->SetValid(EFalse);
   924 	return pPage;
   913 	return pPage;
   925 	}
   914 	}
   926 
   915 
   927 #ifdef _DEBUG
   916 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
   928 /**
   917 /**
   929 Dump cache information, only enabled in debug mode.
   918 Dump cache information, only enabled in debug mode.
   930 @see CDynamicDirCache::Control()
   919 @see CDynamicDirCache::Control()
   931 */
   920 */
   932 void CDynamicDirCache::Info() const
   921 void CDynamicDirCache::Info(TDirCacheInfo* aInfo) const
   933 	{
   922     {
   934 	__PRINT(_L("======== CDynamicDirCache::Info ========="));
   923     __PRINT(_L("======== CDynamicDirCache::Info ========="));
   935 	const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2();
   924     const TUint32 SegmentSizeInBytesLog2 = CCacheMemoryManagerFactory::CacheMemoryManager()->SegmentSizeInBytesLog2();
   936 	// page size
   925     const TUint32 pageMemSizeLog2 = iPageSizeLog2 > SegmentSizeInBytesLog2 ? iPageSizeLog2 : SegmentSizeInBytesLog2;
   937 	__PRINT1(_L("=== Pages size:               [%d Bytes]"), iPageSizeInBytes);
   926     // page size
   938 	__PRINT1(_L("=== Segment size:             [%d Bytes]"), 1 << SegmentSizeInBytesLog2);
   927     __PRINT1(_L("=== Segment size:             [%d Bytes]"), 1 << SegmentSizeInBytesLog2);
   939 
   928     __PRINT1(_L("=== Page data size:           [%d Bytes]"), iPageSizeInBytes);
   940 	// data size:
   929     __PRINT1(_L("=== Page mem size:            [%d Bytes]"), 1 << pageMemSizeLog2);
   941 	__PRINT1(_L("=== Min data size:            [%d Bytes]"), iMinSizeInPages << iPageSizeLog2);
   930 
   942 	__PRINT1(_L("=== Max data size:            [%d Bytes]"), iMaxSizeInPages << iPageSizeLog2);
   931     // cache size in pages
   943 
   932     __PRINT1(_L("=== Min cache size in pages:  [%d]"), iMinSizeInPages);
   944 	// memory size:
   933     __PRINT1(_L("=== Max cache size in pages:  [%d]"), iMaxSizeInPages);
   945 	const TUint32 pageMemSizeLog2 = iPageSizeLog2 > SegmentSizeInBytesLog2 ? iPageSizeLog2 : SegmentSizeInBytesLog2;
   934 
   946 	__PRINT1(_L("=== Min memory size:          [%d Bytes]"), iMinSizeInPages << pageMemSizeLog2);
   935     // locked page num
   947 	__PRINT1(_L("=== Max memory size:          [%d Bytes]"), iMaxSizeInPages << pageMemSizeLog2);
   936     __PRINT1(_L("=== Number of pages locked:   [%d]"), iLockedQCount);
   948 
   937     // unlocked page num
   949 	// reserved pages
   938     __PRINT1(_L("=== Number of pages unlocked: [%d]"), iUnlockedQCount);
   950 	__PRINT1(_L("=== Number of pages reserved: [%d]"), iMinSizeInPages);
   939     __PRINT(_L("=========================================\n"));
   951 	__PRINT1(_L("=== Reserved memory:          [%d Bytes]"), (iMinSizeInPages * PageSizeInSegs()) << SegmentSizeInBytesLog2);
   940     
   952 	// locked page num
   941     ASSERT(aInfo);
   953 	__PRINT1(_L("=== Number of pages locked:   [%d]"), iLockedQCount);
   942     aInfo->iMemorySegmentSize       = 1 << SegmentSizeInBytesLog2;
   954 	__PRINT1(_L("=== Locked memory:            [%d Bytes]"), (iLockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2);
   943     aInfo->iPageSizeInMemory        = PageSizeInSegs() << SegmentSizeInBytesLog2;
   955 	// unlocked page num
   944     aInfo->iPageSizeInData          = iPageSizeInBytes;
   956 	__PRINT1(_L("=== Number of pages unlocked: [%d]"), iUnlockedQCount);
   945     aInfo->iMinCacheSizeInPages     = iMinSizeInPages;
   957 	__PRINT1(_L("=== Unlocked memory:          [%d Bytes]"), (iUnlockedQCount * PageSizeInSegs()) << SegmentSizeInBytesLog2);
   946     aInfo->iMaxCacheSizeInPages     = iMaxSizeInPages;
   958 	}
   947     aInfo->iMinCacheSizeInMemory    = iMinSizeInPages * aInfo->iPageSizeInMemory;
       
   948     aInfo->iMaxCacheSizeInMemory    = iMaxSizeInPages * aInfo->iPageSizeInMemory;
       
   949     aInfo->iLockedPageNumber        = iLockedQCount;
       
   950     aInfo->iUnlockedPageNumber      = iUnlockedQCount;
       
   951     }
   959 
   952 
   960 /**
   953 /**
   961 Dump cache content, only enabled in debug mode.
   954 Dump cache content, only enabled in debug mode.
   962 @see CDynamicDirCache::Control()
   955 @see CDynamicDirCache::Control()
   963 */
   956 */
  1003             pEntry = (TLookupEntry*) iter.Next();
   996             pEntry = (TLookupEntry*) iter.Next();
  1004             };
   997             };
  1005         }
   998         }
  1006     __PRINT(_L("===========================================\n"));
   999     __PRINT(_L("===========================================\n"));
  1007     }
  1000     }
  1008 #endif //_DEBUG
  1001 #endif //#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
  1009 
  1002 
  1010 /**
  1003 /**
  1011 Lock an unlocked page, or do nothing if the page is already locked.
  1004 Lock an unlocked page, or do nothing if the page is already locked.
  1012 @return	TUint8*	pointer of the page to be locked, if locking is successful, otherwise return NULL.
  1005 @return	TUint8*	pointer of the page to be locked, if locking is successful, otherwise return NULL.
  1013 @param	aPage	the pointer of the page to be locked.
  1006 @param	aPage	the pointer of the page to be locked.
  1035 */
  1028 */
  1036 TInt CDynamicDirCache::UnlockPage(TDynamicDirCachePage* aPage)
  1029 TInt CDynamicDirCache::UnlockPage(TDynamicDirCachePage* aPage)
  1037 	{
  1030 	{
  1038 	ASSERT(aPage != NULL);
  1031 	ASSERT(aPage != NULL);
  1039 	__PRINT1(_L("CDynamicDirCache::UnlockPage(%lx)"), aPage->StartPos());
  1032 	__PRINT1(_L("CDynamicDirCache::UnlockPage(%lx)"), aPage->StartPos());
  1040 	TInt r = iCacheMemoryClient->UnlockSegments(aPage->StartPtr(), PageSizeInSegs());
  1033     if (aPage)
  1041 	if (r == KErrNone)
  1034         {
  1042 		{
  1035 		TInt r = iCacheMemoryClient->UnlockSegments(aPage->StartPtr(), PageSizeInSegs());
  1043 		aPage->SetLocked(EFalse);
  1036 		if (r == KErrNone)
  1044 		}
  1037 			{
  1045 	return r;
  1038 			aPage->SetLocked(EFalse);
  1046 	}
  1039 			}
  1047 
  1040 		return r;
       
  1041 		}
       
  1042     return KErrArgument;
       
  1043     }
  1048 /**
  1044 /**
  1049 Decommit a locked or unlocked page.
  1045 Decommit a locked or unlocked page.
  1050 @return	TInt	KErrNone if decommition was successful, otherwise system-wide error code.
  1046 @return	TInt	KErrNone if decommition was successful, otherwise system-wide error code.
  1051 @param	aPage	the pointer of the page to be decommitted.
  1047 @param	aPage	the pointer of the page to be decommitted.
  1052 */
  1048 */