userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp
changeset 90 947f0dc9f7a8
parent 33 0173bcd7697c
child 102 ef2a444a7410
child 176 af6ec97d9189
equal deleted inserted replaced
52:2d65c2f76d7b 90:947f0dc9f7a8
    37 @param	aOwnerCache	pointer of the cache that owns this page
    37 @param	aOwnerCache	pointer of the cache that owns this page
    38 @param	aStartMedPos	the start address on the media that this page caches
    38 @param	aStartMedPos	the start address on the media that this page caches
    39 @param	aStartRamAddr	the start address in the ram that this page content lives
    39 @param	aStartRamAddr	the start address in the ram that this page content lives
    40 */
    40 */
    41 TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr)
    41 TDynamicDirCachePage::TDynamicDirCachePage(CDynamicDirCache* aOwnerCache, TInt64 aStartMedPos, TUint8* aStartRamAddr)
    42 :iStartMedPos(aStartMedPos),
    42                      :iStartMedPos(aStartMedPos),
    43 iStartRamAddr(aStartRamAddr),
    43                       iStartRamAddr(aStartRamAddr),
    44 iOwnerCache(aOwnerCache),
    44                       iOwnerCache(aOwnerCache),
    45 iValid(EFalse),
    45                       iValid(EFalse),
    46 iLocked(EFalse)
    46                       iLocked(EFalse)
    47 	{
    47 	{
    48 	//__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes());
    48 	//__PRINT3(_L("TDynamicDirCachePage::TDynamicDirCachePage(aStartMedPos=%lx, aStartRamAddr=0x%X, aPageSize=%u)"), aStartMedPos, aStartRamAddr, PageSizeInBytes());
    49 	iType = EUnknown;
    49 	iType = EUnknown;
    50 	}
    50 	}
    51 
    51 
   102 /**
   102 /**
   103 Constructor of CDynamicDirCache.
   103 Constructor of CDynamicDirCache.
   104 @param	aDrive	local drive interface to read/write media
   104 @param	aDrive	local drive interface to read/write media
   105 @param	aMinPageNum	the minimum page number for the cache, includes iActive page and locked pages.
   105 @param	aMinPageNum	the minimum page number for the cache, includes iActive page and locked pages.
   106 @param	aMaxPageNum	the maximum page number for the cache, includes iActive page, locked pages and unlocked pages.
   106 @param	aMaxPageNum	the maximum page number for the cache, includes iActive page, locked pages and unlocked pages.
   107 @param	aPageSizeInBytesLog2	the log2 value of page size in bytes, assumes page size is always a power of two
   107     @param	aPageSizeInBytesLog2	Log2 of the page size in bytes, this is the cache read granularity
   108 */
   108     @param  aWrGranularityLog2      Log2(cache write granularity)
   109 CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2)
   109 */
   110 :iPageSizeLog2(aPageSizeInBytesLog2),
   110 CDynamicDirCache::CDynamicDirCache(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeInBytesLog2, TUint32 aWrGranularityLog2)
   111 iMinSizeInPages(aMinPageNum),
   111                  :iPageSizeLog2(aPageSizeInBytesLog2),
   112 iMaxSizeInPages(aMaxPageNum),
   112                   iWrGranularityLog2(aWrGranularityLog2),
   113 iDrive(aDrive),
   113                   iMinSizeInPages(aMinPageNum),
   114 iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   114                   iMaxSizeInPages(aMaxPageNum),
   115 iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   115                   iDrive(aDrive),
   116 iLockedQCount(0),
   116                   iLockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   117 iUnlockedQCount(0),
   117                   iUnlockedQ(_FOFF(TDynamicDirCachePage, iLink)),
   118 iHashFunction(HashFunction),
   118                   iLockedQCount(0),
   119 iIdentityFunction(IdentityFunction),
   119                   iUnlockedQCount(0),
   120 iLookupTable(iHashFunction, iIdentityFunction)
   120                   iHashFunction(HashFunction),
       
   121                   iIdentityFunction(IdentityFunction),
       
   122                   iLookupTable(iHashFunction, iIdentityFunction)
   121 	{
   123 	{
   122 	iPageSizeInBytes = 1 << aPageSizeInBytesLog2;
   124 	iPageSizeInBytes = 1 << aPageSizeInBytesLog2;
   123 	iCacheDisabled = EFalse;
   125 	iCacheDisabled = EFalse;
   124     iMinCacheSizeInBytes = aMinPageNum << aPageSizeInBytesLog2;
   126     iMinCacheSizeInBytes = aMinPageNum << aPageSizeInBytesLog2;
   125     iMaxCacheSizeInBytes = aMaxPageNum << aPageSizeInBytesLog2;
   127     iMaxCacheSizeInBytes = aMaxPageNum << aPageSizeInBytesLog2;
   155 
   157 
   156 
   158 
   157 	// allocate as many permanently locked pages as there are threads - plus one
   159 	// allocate as many permanently locked pages as there are threads - plus one
   158 	// otherwise DoMakePageMRU() won't work properly with only one thread
   160 	// otherwise DoMakePageMRU() won't work properly with only one thread
   159     //-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool)
   161     //-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool)
   160 	iPermanentlyAllocatedPageCount = 1; 
   162 	const TUint KThreadCount = 1;
       
   163 	iPermanentlyAllocatedPageCount = KThreadCount + 1; 
   161 
   164 
   162 	if (iPermanentlyAllocatedPageCount > iMinSizeInPages)
   165 	if (iPermanentlyAllocatedPageCount > iMinSizeInPages)
   163 		iMinSizeInPages = iPermanentlyAllocatedPageCount;
   166 		iMinSizeInPages = iPermanentlyAllocatedPageCount;
   164 
   167 
   165 	for (TUint n=0; n<iPermanentlyAllocatedPageCount; n++)
   168 	for (TUint n=0; n<iPermanentlyAllocatedPageCount; n++)
   172 	}
   175 	}
   173 
   176 
   174 /**
   177 /**
   175 Static factory function of CDynamicDirCache
   178 Static factory function of CDynamicDirCache
   176 */
   179 */
   177 CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, const TDesC& aClientName)
   180 CDynamicDirCache* CDynamicDirCache::NewL(TDriveInterface& aDrive, TUint32 aMinPageNum, TUint32 aMaxPageNum, TUint32 aPageSizeLog2, TUint32 aWrGranularityLog2, const TDesC& aClientName)
   178     {
   181     {
   179     __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2);
   182     __PRINT3(_L("CDynamicDirCache::NewL(MinPageNum=%u, MaxPageNum=%u, page=%u)"), aMinPageNum, aMaxPageNum, 1<<aPageSizeLog2);
   180     CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2);
   183     CDynamicDirCache* pSelf = new (ELeave) CDynamicDirCache(aDrive, aMinPageNum, aMaxPageNum, aPageSizeLog2, aWrGranularityLog2);
   181     CleanupStack::PushL(pSelf);
   184     CleanupStack::PushL(pSelf);
   182     pSelf->ConstructL(aClientName);
   185     pSelf->ConstructL(aClientName);
   183     CleanupStack::Pop();
   186     CleanupStack::Pop();
   184     return pSelf;
   187     return pSelf;
   185     }
   188     }
   336 @param	aPos	the starting position of the media address to be write.
   339 @param	aPos	the starting position of the media address to be write.
   337 @param	aData	the starting address that the writing content lives in the ram.
   340 @param	aData	the starting address that the writing content lives in the ram.
   338 @param	aDataLen	the length of the content to be written.
   341 @param	aDataLen	the length of the content to be written.
   339 @pre	aDataLen	should be no more than page size.
   342 @pre	aDataLen	should be no more than page size.
   340 */
   343 */
   341 void CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
   344 TDynamicDirCachePage* CDynamicDirCache::WriteDataOntoSinglePageL(TInt64 aPos, const TUint8* aData, TUint32 aDataLen)
   342 	{
   345 	{
   343 	ASSERT(aDataLen <= iPageSizeInBytes);
   346 	ASSERT(aDataLen <= iPageSizeInBytes);
   344     //-- the data section is in the cache page entirely, take data directly from the cache
   347     //-- the data section is in the cache page entirely, take data directly from the cache
   345 	TDynamicDirCachePage* pPage = FindPageByPos(aPos);
   348 	TDynamicDirCachePage* pPage = FindPageByPos(aPos);
   346     if (pPage)
   349     if (pPage)
   376 		UnlockPage(pPage);
   379 		UnlockPage(pPage);
   377 		}
   380 		}
   378 
   381 
   379 	// always make writting events MRU
   382 	// always make writting events MRU
   380 	DoMakePageMRU(aPos);
   383 	DoMakePageMRU(aPos);
   381     return;
   384     
       
   385     return pPage;
   382 	}
   386 	}
   383 
   387 
   384 /**
   388 /**
   385 Implementation of pure virtual function.
   389 Implementation of pure virtual function.
   386 @see	MWTCacheInterface::WriteL()
   390 @see	MWTCacheInterface::WriteL()
   405     TUint32 bytesToPageEnd = (TUint32)(pageStartMedPos + PageSz - aPos);
   409     TUint32 bytesToPageEnd = (TUint32)(pageStartMedPos + PageSz - aPos);
   406 
   410 
   407 //    __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd);
   411 //    __PRINT5(_L("CDynamicDirCache::WriteL: aPos=%lx, aLength=%x, page:%lx, pageSz:%x, bytesToPageEnd=%x"), aPos, dataLen, pageStartMedPos, PageSz, bytesToPageEnd);
   408 
   412 
   409     if(dataLen <= bytesToPageEnd)
   413     if(dataLen <= bytesToPageEnd)
   410         {
   414         {//-- make small write a multiple of a write granularity size (if it is used at all)
   411         WriteDataOntoSinglePageL(aPos, pData, dataLen);
   415          //-- this is not the best way to use write granularity, but we would need to refactor cache pages code to make it normal
       
   416         
       
   417         TDynamicDirCachePage* pPage = WriteDataOntoSinglePageL(aPos, pData, dataLen);
       
   418         TPtrC8 desBlock(aDes);
       
   419 
       
   420         if(iWrGranularityLog2)
       
   421             {//-- write granularity is used
       
   422             const TInt64  newPos = (aPos >> iWrGranularityLog2)  << iWrGranularityLog2; //-- round position down to the granularity unit size
       
   423             TUint32 newLen = (TUint32)(aPos - newPos)+dataLen;
       
   424             newLen = RoundUp(newLen, iWrGranularityLog2);
       
   425 
       
   426             const TUint8* pd = pPage->PtrInPage(newPos);
       
   427             desBlock.Set(pd, newLen);
       
   428             aPos = newPos;
       
   429             
       
   430             }
       
   431 
       
   432         //-- write data to the media
       
   433         const TInt nErr = iDrive.WriteCritical(aPos, desBlock);
       
   434         if(nErr != KErrNone)
       
   435             {//-- some serious problem occured during writing, invalidate cache.
       
   436             InvalidateCache();
       
   437             User::Leave(nErr);
       
   438             }
       
   439 
       
   440 
   412         }
   441         }
   413     else
   442     else
   414         {
   443         {//-- Data to be written cross cache page boundary or probably we have more than 1 page to write
       
   444          //-- this is a very rare case.   
   415         __PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!"));
   445         __PRINT(_L("CDynamicDirCache::WriteL() CROSS PAGE!"));
   416 
   446 
   417         //-- Data to be written cross cache page boundary or probably we have more than 1 page to write
   447         //-- Data to be written cross cache page boundary or probably we have more than 1 page to write
   418         TInt64  currMediaPos(aPos);
   448         TInt64  currMediaPos(aPos);
   419 
   449 
   437         //-- 3. write the rest of the data
   467         //-- 3. write the rest of the data
   438         if(dataLen > 0)
   468         if(dataLen > 0)
   439             {
   469             {
   440             WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
   470             WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
   441             }
   471             }
   442         }// else(dataLen <= bytesToPageEnd)
       
   443 
       
   444 
   472 
   445     //-- write data to the media
   473     //-- write data to the media
   446     const TInt nErr = iDrive.WriteCritical(aPos,aDes);
   474     const TInt nErr = iDrive.WriteCritical(aPos,aDes);
   447     if(nErr != KErrNone)
   475     if(nErr != KErrNone)
   448         {//-- some serious problem occured during writing, invalidate cache.
   476         {//-- some serious problem occured during writing, invalidate cache.
   449         InvalidateCache();
   477         InvalidateCache();
   450         User::Leave(nErr);
   478         User::Leave(nErr);
   451         }
   479         }
       
   480 
       
   481 
       
   482         }// else(dataLen <= bytesToPageEnd)
       
   483 
       
   484 
   452 	}
   485 	}
   453 
   486 
   454 /**
   487 /**
   455     Invalidate the cache
   488     Invalidate the cache
   456     @see	MWTCacheInterface::InvalidateCache()
   489     @see	MWTCacheInterface::InvalidateCache()
   516 
   549 
   517 /**
   550 /**
   518 Implementation of pure virtual function.
   551 Implementation of pure virtual function.
   519 @see	MWTCacheInterface::PosCached()
   552 @see	MWTCacheInterface::PosCached()
   520 */
   553 */
   521 TUint32 CDynamicDirCache::PosCached(const TInt64& aPos, TInt64& aCachedPosStart)
   554 TUint32 CDynamicDirCache::PosCached(TInt64 aPos)
   522 	{
   555 	{
   523 	const TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   556 	const TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   524 
   557 
   525 	// only search the page in lookup table
   558 	// only search the page in lookup table
   526 	// NOTE: we don't count the active page into acount here,
   559 	// NOTE: we don't count the active page into acount here,
   533 		if (LockPage(pPage) != NULL)
   566 		if (LockPage(pPage) != NULL)
   534 			{
   567 			{
   535 //			__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos);
   568 //			__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) found on Unlocked Queue!"), aPos);
   536 			// have to unlock it before returning, otherwise there will be memory leak
   569 			// have to unlock it before returning, otherwise there will be memory leak
   537 			UnlockPage(pPage);
   570 			UnlockPage(pPage);
   538     	    aCachedPosStart = pPage->StartPos();
       
   539 			return pPage->PageSizeInBytes();
   571 			return pPage->PageSizeInBytes();
   540 			}
   572 			}
   541 		else	// if the unlocked page is not valid anymore, remove it
   573 		else	// if the unlocked page is not valid anymore, remove it
   542 			{
   574 			{
   543     		DeQueue(pPage);
   575     		DeQueue(pPage);
   549 		}
   581 		}
   550 	// otherwise if page is already locked or valid active page
   582 	// otherwise if page is already locked or valid active page
   551 	else if (pPage)
   583 	else if (pPage)
   552 		{
   584 		{
   553 		__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
   585 		__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
   554 	    aCachedPosStart = pPage->StartPos();
       
   555 		return pPage->PageSizeInBytes();
   586 		return pPage->PageSizeInBytes();
   556 		}
   587 		}
   557 
   588 
   558 	// page is not found or not valid anymore
   589 	// page is not found or not valid anymore
   559 	return 0;
   590 	return 0;
   647 
   678 
   648 void CDynamicDirCache::DoMakePageMRU(TInt64 aPos)
   679 void CDynamicDirCache::DoMakePageMRU(TInt64 aPos)
   649 	{
   680 	{
   650 //	__PRINT1(_L("MakePageMRU (%lx)"), aPos);
   681 //	__PRINT1(_L("MakePageMRU (%lx)"), aPos);
   651 //	__PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages);
   682 //	__PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages);
       
   683 	// check there are at least two locked pages
       
   684 	ASSERT(iLockedQCount > 1);
       
   685 	
   652 	// check the MRU page first, if it is already the MRU page, we can return immediately
   686 	// check the MRU page first, if it is already the MRU page, we can return immediately
   653 	TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   687 	TInt64 pageStartMedPos = CalcPageStartPos(aPos);
   654 	if (!iLockedQ.IsEmpty())
   688 	if (!iLockedQ.IsEmpty())
   655 		{
   689 		{
   656 		if (iLockedQ.First()->StartPos() == pageStartMedPos)
   690 		if (iLockedQ.First()->StartPos() == pageStartMedPos)
   785 	if (activePage->StartPos() == pageStartMedPos && activePage->IsValid())
   819 	if (activePage->StartPos() == pageStartMedPos && activePage->IsValid())
   786 		{
   820 		{
   787 		return activePage;
   821 		return activePage;
   788 		}
   822 		}
   789 
   823 
   790 	__PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, activePage->StartPos());
   824 	//__PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, activePage->StartPos());
   791 
   825 
   792 	activePage->Deque();
   826 	activePage->Deque();
   793 	LookupTblRemove(activePage->StartPos());
   827 	LookupTblRemove(activePage->StartPos());
   794 
   828 
   795 	// set start med pos value, no other effects, only available to active page
   829 	// set start med pos value, no other effects, only available to active page
   917 /**
   951 /**
   918 Dump cache content, only enabled in debug mode.
   952 Dump cache content, only enabled in debug mode.
   919 @see CDynamicDirCache::Control()
   953 @see CDynamicDirCache::Control()
   920 */
   954 */
   921 void CDynamicDirCache::Dump()
   955 void CDynamicDirCache::Dump()
   922 	{
   956     {
   923 	__PRINT(_L("======== CDynamicDirCache::Dump ========="));
   957     __PRINT(_L("======== CDynamicDirCache::Dump ========="));
   924 	if (!iLockedQ.IsEmpty())
   958     if (!iLockedQ.IsEmpty())
   925 		{
   959         {
   926 		TDblQueIter<TDynamicDirCachePage> q(iLockedQ);
   960         TDblQueIter<TDynamicDirCachePage> q(iLockedQ);
   927 		q.SetToFirst();
   961         q.SetToFirst();
   928 		TInt i = 0;
   962         TInt i = 0;
   929 		while((TDynamicDirCachePage*)q)
   963         while((TDynamicDirCachePage*)q)
   930 			{
   964             {
   931 			TDynamicDirCachePage* pP = q++;
   965             TDynamicDirCachePage* pP = q++;
   932 			__PRINT5(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   966             __PRINT5(_L("=== CDynamicDirCache::iLockedQ      [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   933 			}
   967             }
   934 		}
   968         }
   935 	if (!iUnlockedQ.IsEmpty())
   969     __PRINT(_L("=== CDynamicDirCache:: --------------------"));
   936 		{
   970 
   937 		TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ);
   971     if (!iUnlockedQ.IsEmpty())
   938 		q.SetToFirst();
   972         {
   939 		TInt i = 0;
   973         TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ);
   940 		while((TDynamicDirCachePage*)q)
   974         q.SetToFirst();
   941 			{
   975         TInt i = 0;
   942 			TDynamicDirCachePage* pP = q++;
   976         while((TDynamicDirCachePage*)q)
   943 			__PRINT5(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   977             {
   944 			}
   978             TDynamicDirCachePage* pP = q++;
   945 		}
   979             __PRINT5(_L("=== CDynamicDirCache::iUnlockedQ    [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   946 
   980             }
   947 	if (iLookupTable.Count())
   981         }
   948 		{
   982     __PRINT(_L("=== CDynamicDirCache:: --------------------"));
   949 		TInt i = 0;
   983 
   950 		THashSetIter<TLookupEntry> iter(iLookupTable);
   984     if (iLookupTable.Count())
   951 		TLookupEntry* pEntry;
   985         {
   952 		pEntry = (TLookupEntry*) iter.Next();
   986         TInt i = 0;
   953 		while(pEntry)
   987         THashSetIter<TLookupEntry> iter(iLookupTable);
   954 			{
   988         TLookupEntry* pEntry;
   955 			TDynamicDirCachePage* pP = pEntry->iPage;
   989         pEntry = (TLookupEntry*) iter.Next();
   956 			__PRINT5(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   990         while(pEntry)
   957 			pEntry = (TLookupEntry*) iter.Next();
   991             {
   958 			};
   992             TDynamicDirCachePage* pP = pEntry->iPage;
   959 		}
   993             __PRINT5(_L("=== CDynamicDirCache::iLookupTable  [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
   960 	__PRINT(_L("===========================================\n"));
   994             pEntry = (TLookupEntry*) iter.Next();
   961 	}
   995             };
       
   996         }
       
   997     __PRINT(_L("===========================================\n"));
       
   998     }
   962 #endif //_DEBUG
   999 #endif //_DEBUG
   963 
  1000 
   964 /**
  1001 /**
   965 Lock an unlocked page, or do nothing if the page is already locked.
  1002 Lock an unlocked page, or do nothing if the page is already locked.
   966 @return	TUint8*	pointer of the page to be locked, if locking is successful, otherwise return NULL.
  1003 @return	TUint8*	pointer of the page to be locked, if locking is successful, otherwise return NULL.