kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
child 294 039a3e647356
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp	Tue Aug 31 16:34:26 2010 +0300
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp	Wed Sep 01 12:34:56 2010 +0100
@@ -67,7 +67,7 @@
 	enum TSwapState
 		{
 		EStateUnreserved = 0,	///< swap space not yet reserved, or page is being decommitted
-		EStateBlank      = 1,	///< swap page has never been written or the last write failed
+		EStateBlank      = 1,	///< swap page has never been written
 		EStateWritten    = 2,	///< swap page has been written out at least once
 		EStateWriting    = 3	///< swap page is in the process of being written out
 		};
@@ -157,26 +157,26 @@
 
 private:
 	/**
-	The paging device used for accessing the backing store.
-	This is set by #InstallPagingDevice.
+	   The paging device used for accessing the backing store.
+	   This is set by #InstallPagingDevice.
 	*/
 	DPagingDevice* iDevice;
 
 	/**
-	The instance of #DSwapManager being used by this manager.
+	   The instance of #DSwapManager being used by this manager.
 	*/
 	DSwapManager* iSwapManager;
 
 	/**
-	Whether to read and write pages by physical address without mapping them first.
+	   Whether to read and write pages by physical address without mapping them first.
 
-	Set if the paging media driver supports it.
+	   Set if the paging media driver supports it.
 	*/
 	TBool iUsePhysicalAccess;
 
 public:
 	/**
-	The single instance of this manager class.
+	   The single instance of this manager class.
 	*/
 	static DDataPagedMemoryManager TheManager;
 	};
@@ -187,9 +187,9 @@
 
 
 /**
-Create a swap manager.
+   Create a swap manager.
 
-@param	aDevice	The demand paging device for access to the swap.
+   @param	aDevice	The demand paging device for access to the swap.
 */
 TInt DSwapManager::Create(DPagingDevice* aDevice)
 	{
@@ -231,7 +231,7 @@
 inline DSwapManager::TSwapState DSwapManager::SwapState(TUint aSwapData)
 	{
 	TSwapState state = (TSwapState)(aSwapData & ESwapStateMask);
-	__NK_ASSERT_DEBUG(state >= EStateBlank || aSwapData == 0);
+	__NK_ASSERT_DEBUG(state >= EStateWritten || (aSwapData & ~ESwapStateMask) == 0);
 	return state;
 	}
 
@@ -244,19 +244,18 @@
 
 inline TUint DSwapManager::SwapData(TSwapState aSwapState, TInt aSwapIndex)
 	{
-	__NK_ASSERT_DEBUG(aSwapIndex < (1 << (32 - ESwapIndexShift)));
 	return (aSwapIndex << ESwapIndexShift) | aSwapState;
 	}
 
 
 /**
-Allocate one or more page's worth of space within the swap area.
+   Allocate one or more page's worth of space within the swap area.
 
-The location is represented by a page-based index into the swap area.
+   The location is represented by a page-based index into the swap area.
 
-@param aCount The number of page's worth of space to allocate.
+   @param aCount The number of page's worth of space to allocate.
 
-@return The swap index of the first location allocated.
+   @return The swap index of the first location allocated.
 */
 TInt DSwapManager::AllocSwapIndex(TUint aCount)
 	{
@@ -314,9 +313,9 @@
 
 
 /**
-Free one page's worth of space within the swap area.
+   Free one page's worth of space within the swap area.
 
-The index must have been previously allocated with AllocSwapIndex().
+   The index must have been previously allocated with AllocSwapIndex().
 */
 void DSwapManager::FreeSwapIndex(TInt aSwapIndex)
 	{
@@ -329,15 +328,15 @@
 
 
 /**
-Reserve some swap pages for the requested region of the memory object
+   Reserve some swap pages for the requested region of the memory object
 
-@param aMemory		The memory object to reserve pages for.
-@param aStartIndex	The page index in the memory object of the start of the region.
-@param aPageCount	The number of pages to reserve.
+   @param aMemory		The memory object to reserve pages for.
+   @param aStartIndex	The page index in the memory object of the start of the region.
+   @param aPageCount	The number of pages to reserve.
 
-@return KErrNone on success, KErrNoMemory if not enough swap space available.
-@pre aMemory's lock is held.
-@post aMemory's lock is held.
+   @return KErrNone on success, KErrNoMemory if not enough swap space available.
+   @pre aMemory's lock is held.
+   @post aMemory's lock is held.
 */
 TInt DSwapManager::ReserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
 	{
@@ -370,15 +369,15 @@
 
 
 /**
-Unreserve swap pages for the requested region of the memory object.
+   Unreserve swap pages for the requested region of the memory object.
 
-@param aMemory		The memory object to unreserve pages for.
-@param aStartIndex	The page index in the memory object of the start of the region.
-@param aPageCount	The number of pages to unreserve.
+   @param aMemory		The memory object to unreserve pages for.
+   @param aStartIndex	The page index in the memory object of the start of the region.
+   @param aPageCount	The number of pages to unreserve.
 
-@return The number of pages freed.
-@pre aMemory's lock is held.
-@post aMemory's lock is held.
+   @return The number of pages freed.
+   @pre aMemory's lock is held.
+   @post aMemory's lock is held.
 */
 TInt DSwapManager::UnreserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
 	{
@@ -425,13 +424,13 @@
 
 
 /**
-Determine whether the specified pages in the memory object have swap reserved for them.
+   Determine whether the specified pages in the memory object have swap reserved for them.
 
-@param aMemory		The memory object that owns the pages.
-@param aStartIndex	The first index of the pages to check.
-@param aPageCount	The number of pages to check.
+   @param aMemory		The memory object that owns the pages.
+   @param aStartIndex	The first index of the pages to check.
+   @param aPageCount	The number of pages to check.
 
-@return ETrue if swap is reserved for all the pages, EFalse otherwise.
+   @return ETrue if swap is reserved for all the pages, EFalse otherwise.
 */
 TBool DSwapManager::IsReserved(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
 	{// MmuLock required to protect manager data.
@@ -452,19 +451,20 @@
 
 
 /**
-Read from the swap the specified pages associated with the memory object.
+   Read from the swap the specified pages associated with the memory object.
 
-@param aMemory 	The memory object to read the pages for
-@param aIndex	The index of the first page within the memory object.
-@param aCount	The number of pages to read.
-@param aLinAddr	The address to copy the pages to.
-@param aRequest	The request to use for the read.
-@param aPhysAddrs	An array of the physical addresses for each page to read in.
+   @param aMemory 	The memory object to read the pages for
+   @param aIndex	The index of the first page within the memory object.
+   @param aCount	The number of pages to read.
+   @param aLinAddr	The address to copy the pages to.
+   @param aRequest	The request to use for the read.
+   @param aPhysAddrs	An array of the physical addresses for each page to read in.
 */
 TInt DSwapManager::ReadSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs)
 	{
 	__ASSERT_CRITICAL;
 	
+	TInt r = KErrNone;
 	const TUint readUnitShift = iDevice->iReadUnitShift;
 	TUint readSize = KPageSize >> readUnitShift;
 	TThreadMessage message;
@@ -477,36 +477,24 @@
 		MmuLock::Lock();	// MmuLock required for atomic access to manager data.
 		TUint swapData = aMemory->PagingManagerData(index);
 		TSwapState state = SwapState(swapData);
-		TUint swapPage = SwapIndex(swapData);
 
 		if (state == EStateUnreserved)
-			{
-			// This page is not committed to the memory object
+			{// This page is not committed to the memory object
 			MmuLock::Unlock();
 			return KErrNotFound;			
 			}
 		else if (state == EStateBlank)
-			{
-			if (swapPage != 0)
-				{
-				// An error occured while writing the page out, so report it now
-				MmuLock::Unlock();
-				return -swapPage; 
-				}
-			else
+			{// This page has not been written to yet so don't read from swap 
+			// just wipe it if required.
+			TUint allocFlags = aMemory->RamAllocFlags();
+			MmuLock::Unlock();
+			TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
+			if (wipePages)
 				{
-				// This page has not been written to yet so don't read from swap 
-				// just wipe it if required.
-				TUint allocFlags = aMemory->RamAllocFlags();
-				MmuLock::Unlock();
-				TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
-				if (wipePages)
-					{
-					TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ?
-						(allocFlags >> Mmu::EAllocWipeByteShift) & 0xff :
-						0x03;
-					memset((TAny*)aLinAddr, wipeByte, KPageSize);
-					}
+				TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ?
+					(allocFlags >> Mmu::EAllocWipeByteShift) & 0xff :
+					0x03;
+				memset((TAny*)aLinAddr, wipeByte, KPageSize);
 				}
 			}
 		else
@@ -518,35 +506,33 @@
 			// OK to release as if the object's data is decommitted the pager 
 			// will check that data is still valid before mapping it.
 			MmuLock::Unlock();
-			TUint readStart = (swapPage << KPageShift) >> readUnitShift;
+			TUint readStart = (SwapIndex(swapData) << KPageShift) >> readUnitShift;
 			START_PAGING_BENCHMARK;
-			TInt r = iDevice->Read(&message, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
+			r = iDevice->Read(&message, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
+			if (r != KErrNone)
+				__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::ReadSwapPages: error reading media at %08x + %x: %d", readStart << readUnitShift, readSize << readUnitShift, r));				
+			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
 			END_PAGING_BENCHMARK(EPagingBmReadDataMedia);
-			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore shouldn't fail with KErrNoMemory
-			if (r != KErrNone)
-				__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::ReadSwapPages: error reading media at %08x + %x: %d", readStart << readUnitShift, readSize << readUnitShift, r));
-			r = ThePager.EmbedErrorContext(EPagingErrorContextDataRead, r);
-			if (r != KErrNone)
-				return r;
+			__NK_ASSERT_ALWAYS(r == KErrNone);
 			}
 		END_PAGING_BENCHMARK(EPagingBmReadDataPage);
 		}
-	
-	return KErrNone;
+
+	return r;
 	}
 
 
 /**
-Write the specified memory object's pages from the RAM into the swap.
+   Write the specified memory object's pages from the RAM into the swap.
 
-@param	aMemory		The memory object who owns the pages.
-@param	aIndex		The index within the memory object.
-@param 	aCount		The number of pages to write out.
-@param	aLinAddr	The location of the pages to write out.
-@param  aBackground Whether this is being called in the background by the page cleaning thread
-                    as opposed to on demand when a free page is required.
+   @param	aMemory		The memory object who owns the pages.
+   @param	aIndex		The index within the memory object.
+   @param 	aCount		The number of pages to write out.
+   @param	aLinAddr	The location of the pages to write out.
+   @param  aBackground Whether this is being called in the background by the page cleaning thread
+   as opposed to on demand when a free page is required.
 
-@pre Called with page cleaning lock held
+   @pre Called with page cleaning lock held
 */
 TInt DSwapManager::WriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs, TBool aBackground)
 	{
@@ -640,16 +626,14 @@
 		r = iDevice->WritePhysical(&msg, aPhysAddrs, aCount, writeOffset, aBackground);
 	else
 		r = iDevice->Write(&msg, aLinAddr + (aPageIndex << KPageShift), writeOffset, writeSize, aBackground);
-	END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
 		
 	if (r != KErrNone)
 		{
 		__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::WriteSwapPages: error writing media from %08x to %08x + %x: %d", aLinAddr, writeOffset << readUnitShift, writeSize << readUnitShift, r));
-		if (r > 0)
-			r = KErrGeneral;
 		}
 	__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
-	r = ThePager.EmbedErrorContext(EPagingErrorContextDataWrite, r); 
+	__NK_ASSERT_ALWAYS(r == KErrNone);
+	END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
 
 	TUint i;
 	TUint swapData[KMaxPagesToClean];
@@ -663,12 +647,8 @@
 		__NK_ASSERT_DEBUG(s == EStateUnreserved || s == EStateWriting);
 		if (s == EStateWriting)
 			{
-			// Store the new swap location and mark the page as saved, or if an error occured then
-			// record the error code instead
-			TUint swapData = (r == KErrNone) 
-				? SwapData(EStateWritten, aSwapIndex + i)
-				: SwapData(EStateBlank, -r);
-			aMemory[i]->SetPagingManagerData(aIndex[i], swapData);
+			// Store the new swap location and mark the page as saved.
+			aMemory[i]->SetPagingManagerData(aIndex[i], SwapData(EStateWritten, aSwapIndex + i));
 			}
 		}
 	MmuLock::Unlock();
@@ -676,17 +656,15 @@
 	for (i = 0 ; i < aCount ; ++i)
 		{
 		TSwapState s = SwapState(swapData[i]);
-		if (s == EStateUnreserved || s == EStateBlank)
+		if (s == EStateUnreserved)
 			{
-			// The page was either decommitted while we were cleaning it, or an error occured while
-			// writing.  Free the swap page and don't modify the state.
+			// The page was decommitted while we were cleaning it, so free the swap page we
+			// allocated and continue, leaving this page in the unreserved state.
 			FreeSwapIndex(aSwapIndex + i);
 			}
 		}
 
-	// write errors are not reported at this point as this will just kill a thread unrelated to the
-	// one whose data has been lost
-	return KErrNone;  
+	return KErrNone;
 	}