kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
child 294 039a3e647356
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
    65 	/// Note that this does not always correspond to the state of the page in RAM - for example a
    65 	/// Note that this does not always correspond to the state of the page in RAM - for example a
    66 	/// page can be dirty in RAM but blank in swap if it has never been written out.
    66 	/// page can be dirty in RAM but blank in swap if it has never been written out.
    67 	enum TSwapState
    67 	enum TSwapState
    68 		{
    68 		{
    69 		EStateUnreserved = 0,	///< swap space not yet reserved, or page is being decommitted
    69 		EStateUnreserved = 0,	///< swap space not yet reserved, or page is being decommitted
    70 		EStateBlank      = 1,	///< swap page has never been written or the last write failed
    70 		EStateBlank      = 1,	///< swap page has never been written
    71 		EStateWritten    = 2,	///< swap page has been written out at least once
    71 		EStateWritten    = 2,	///< swap page has been written out at least once
    72 		EStateWriting    = 3	///< swap page is in the process of being written out
    72 		EStateWriting    = 3	///< swap page is in the process of being written out
    73 		};
    73 		};
    74 	
    74 	
    75 	enum
    75 	enum
   155 private:
   155 private:
   156 	TInt WritePages(DMemoryObject** aMemory, TUint* aIndex, TPhysAddr* aPages, TUint aCount, DPageWriteRequest *aRequest, TBool aAnyExecutable, TBool aBackground);
   156 	TInt WritePages(DMemoryObject** aMemory, TUint* aIndex, TPhysAddr* aPages, TUint aCount, DPageWriteRequest *aRequest, TBool aAnyExecutable, TBool aBackground);
   157 
   157 
   158 private:
   158 private:
   159 	/**
   159 	/**
   160 	The paging device used for accessing the backing store.
   160 	   The paging device used for accessing the backing store.
   161 	This is set by #InstallPagingDevice.
   161 	   This is set by #InstallPagingDevice.
   162 	*/
   162 	*/
   163 	DPagingDevice* iDevice;
   163 	DPagingDevice* iDevice;
   164 
   164 
   165 	/**
   165 	/**
   166 	The instance of #DSwapManager being used by this manager.
   166 	   The instance of #DSwapManager being used by this manager.
   167 	*/
   167 	*/
   168 	DSwapManager* iSwapManager;
   168 	DSwapManager* iSwapManager;
   169 
   169 
   170 	/**
   170 	/**
   171 	Whether to read and write pages by physical address without mapping them first.
   171 	   Whether to read and write pages by physical address without mapping them first.
   172 
   172 
   173 	Set if the paging media driver supports it.
   173 	   Set if the paging media driver supports it.
   174 	*/
   174 	*/
   175 	TBool iUsePhysicalAccess;
   175 	TBool iUsePhysicalAccess;
   176 
   176 
   177 public:
   177 public:
   178 	/**
   178 	/**
   179 	The single instance of this manager class.
   179 	   The single instance of this manager class.
   180 	*/
   180 	*/
   181 	static DDataPagedMemoryManager TheManager;
   181 	static DDataPagedMemoryManager TheManager;
   182 	};
   182 	};
   183 
   183 
   184 
   184 
   185 DDataPagedMemoryManager DDataPagedMemoryManager::TheManager;
   185 DDataPagedMemoryManager DDataPagedMemoryManager::TheManager;
   186 DPagedMemoryManager* TheDataPagedMemoryManager = &DDataPagedMemoryManager::TheManager;
   186 DPagedMemoryManager* TheDataPagedMemoryManager = &DDataPagedMemoryManager::TheManager;
   187 
   187 
   188 
   188 
   189 /**
   189 /**
   190 Create a swap manager.
   190    Create a swap manager.
   191 
   191 
   192 @param	aDevice	The demand paging device for access to the swap.
   192    @param	aDevice	The demand paging device for access to the swap.
   193 */
   193 */
   194 TInt DSwapManager::Create(DPagingDevice* aDevice)
   194 TInt DSwapManager::Create(DPagingDevice* aDevice)
   195 	{
   195 	{
   196 	__ASSERT_COMPILE(!(ESwapIndexMask & ESwapStateMask));
   196 	__ASSERT_COMPILE(!(ESwapIndexMask & ESwapStateMask));
   197 	__NK_ASSERT_DEBUG(iDevice == NULL);
   197 	__NK_ASSERT_DEBUG(iDevice == NULL);
   229 
   229 
   230 
   230 
   231 inline DSwapManager::TSwapState DSwapManager::SwapState(TUint aSwapData)
   231 inline DSwapManager::TSwapState DSwapManager::SwapState(TUint aSwapData)
   232 	{
   232 	{
   233 	TSwapState state = (TSwapState)(aSwapData & ESwapStateMask);
   233 	TSwapState state = (TSwapState)(aSwapData & ESwapStateMask);
   234 	__NK_ASSERT_DEBUG(state >= EStateBlank || aSwapData == 0);
   234 	__NK_ASSERT_DEBUG(state >= EStateWritten || (aSwapData & ~ESwapStateMask) == 0);
   235 	return state;
   235 	return state;
   236 	}
   236 	}
   237 
   237 
   238 
   238 
   239 inline TInt DSwapManager::SwapIndex(TUint aSwapData)
   239 inline TInt DSwapManager::SwapIndex(TUint aSwapData)
   242 	}
   242 	}
   243 
   243 
   244 
   244 
   245 inline TUint DSwapManager::SwapData(TSwapState aSwapState, TInt aSwapIndex)
   245 inline TUint DSwapManager::SwapData(TSwapState aSwapState, TInt aSwapIndex)
   246 	{
   246 	{
   247 	__NK_ASSERT_DEBUG(aSwapIndex < (1 << (32 - ESwapIndexShift)));
       
   248 	return (aSwapIndex << ESwapIndexShift) | aSwapState;
   247 	return (aSwapIndex << ESwapIndexShift) | aSwapState;
   249 	}
   248 	}
   250 
   249 
   251 
   250 
   252 /**
   251 /**
   253 Allocate one or more page's worth of space within the swap area.
   252    Allocate one or more page's worth of space within the swap area.
   254 
   253 
   255 The location is represented by a page-based index into the swap area.
   254    The location is represented by a page-based index into the swap area.
   256 
   255 
   257 @param aCount The number of page's worth of space to allocate.
   256    @param aCount The number of page's worth of space to allocate.
   258 
   257 
   259 @return The swap index of the first location allocated.
   258    @return The swap index of the first location allocated.
   260 */
   259 */
   261 TInt DSwapManager::AllocSwapIndex(TUint aCount)
   260 TInt DSwapManager::AllocSwapIndex(TUint aCount)
   262 	{
   261 	{
   263 	TRACE2(("DSwapManager::AllocSwapIndex %d", aCount));
   262 	TRACE2(("DSwapManager::AllocSwapIndex %d", aCount));
   264 		
   263 		
   312 	return swapIndex;
   311 	return swapIndex;
   313 	}
   312 	}
   314 
   313 
   315 
   314 
   316 /**
   315 /**
   317 Free one page's worth of space within the swap area.
   316    Free one page's worth of space within the swap area.
   318 
   317 
   319 The index must have been previously allocated with AllocSwapIndex().
   318    The index must have been previously allocated with AllocSwapIndex().
   320 */
   319 */
   321 void DSwapManager::FreeSwapIndex(TInt aSwapIndex)
   320 void DSwapManager::FreeSwapIndex(TInt aSwapIndex)
   322 	{
   321 	{
   323 	__NK_ASSERT_DEBUG(aSwapIndex >= 0 && aSwapIndex < iBitMap->iSize);
   322 	__NK_ASSERT_DEBUG(aSwapIndex >= 0 && aSwapIndex < iBitMap->iSize);
   324 	DoDeleteNotify(aSwapIndex);
   323 	DoDeleteNotify(aSwapIndex);
   327 	NKern::FMSignal(&iSwapLock);
   326 	NKern::FMSignal(&iSwapLock);
   328 	}
   327 	}
   329 
   328 
   330 
   329 
   331 /**
   330 /**
   332 Reserve some swap pages for the requested region of the memory object
   331    Reserve some swap pages for the requested region of the memory object
   333 
   332 
   334 @param aMemory		The memory object to reserve pages for.
   333    @param aMemory		The memory object to reserve pages for.
   335 @param aStartIndex	The page index in the memory object of the start of the region.
   334    @param aStartIndex	The page index in the memory object of the start of the region.
   336 @param aPageCount	The number of pages to reserve.
   335    @param aPageCount	The number of pages to reserve.
   337 
   336 
   338 @return KErrNone on success, KErrNoMemory if not enough swap space available.
   337    @return KErrNone on success, KErrNoMemory if not enough swap space available.
   339 @pre aMemory's lock is held.
   338    @pre aMemory's lock is held.
   340 @post aMemory's lock is held.
   339    @post aMemory's lock is held.
   341 */
   340 */
   342 TInt DSwapManager::ReserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   341 TInt DSwapManager::ReserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   343 	{
   342 	{
   344 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
   343 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
   345 
   344 
   368 	return KErrNone;
   367 	return KErrNone;
   369 	}
   368 	}
   370 
   369 
   371 
   370 
   372 /**
   371 /**
   373 Unreserve swap pages for the requested region of the memory object.
   372    Unreserve swap pages for the requested region of the memory object.
   374 
   373 
   375 @param aMemory		The memory object to unreserve pages for.
   374    @param aMemory		The memory object to unreserve pages for.
   376 @param aStartIndex	The page index in the memory object of the start of the region.
   375    @param aStartIndex	The page index in the memory object of the start of the region.
   377 @param aPageCount	The number of pages to unreserve.
   376    @param aPageCount	The number of pages to unreserve.
   378 
   377 
   379 @return The number of pages freed.
   378    @return The number of pages freed.
   380 @pre aMemory's lock is held.
   379    @pre aMemory's lock is held.
   381 @post aMemory's lock is held.
   380    @post aMemory's lock is held.
   382 */
   381 */
   383 TInt DSwapManager::UnreserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   382 TInt DSwapManager::UnreserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   384 	{
   383 	{
   385 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
   384 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
   386 
   385 
   423 	return freedPages;
   422 	return freedPages;
   424 	}
   423 	}
   425 
   424 
   426 
   425 
   427 /**
   426 /**
   428 Determine whether the specified pages in the memory object have swap reserved for them.
   427    Determine whether the specified pages in the memory object have swap reserved for them.
   429 
   428 
   430 @param aMemory		The memory object that owns the pages.
   429    @param aMemory		The memory object that owns the pages.
   431 @param aStartIndex	The first index of the pages to check.
   430    @param aStartIndex	The first index of the pages to check.
   432 @param aPageCount	The number of pages to check.
   431    @param aPageCount	The number of pages to check.
   433 
   432 
   434 @return ETrue if swap is reserved for all the pages, EFalse otherwise.
   433    @return ETrue if swap is reserved for all the pages, EFalse otherwise.
   435 */
   434 */
   436 TBool DSwapManager::IsReserved(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   435 TBool DSwapManager::IsReserved(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
   437 	{// MmuLock required to protect manager data.
   436 	{// MmuLock required to protect manager data.
   438 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   437 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
   439 	__NK_ASSERT_DEBUG(aStartIndex < aMemory->iSizeInPages);
   438 	__NK_ASSERT_DEBUG(aStartIndex < aMemory->iSizeInPages);
   450 	return ETrue;
   449 	return ETrue;
   451 	}
   450 	}
   452 
   451 
   453 
   452 
   454 /**
   453 /**
   455 Read from the swap the specified pages associated with the memory object.
   454    Read from the swap the specified pages associated with the memory object.
   456 
   455 
   457 @param aMemory 	The memory object to read the pages for
   456    @param aMemory 	The memory object to read the pages for
   458 @param aIndex	The index of the first page within the memory object.
   457    @param aIndex	The index of the first page within the memory object.
   459 @param aCount	The number of pages to read.
   458    @param aCount	The number of pages to read.
   460 @param aLinAddr	The address to copy the pages to.
   459    @param aLinAddr	The address to copy the pages to.
   461 @param aRequest	The request to use for the read.
   460    @param aRequest	The request to use for the read.
   462 @param aPhysAddrs	An array of the physical addresses for each page to read in.
   461    @param aPhysAddrs	An array of the physical addresses for each page to read in.
   463 */
   462 */
   464 TInt DSwapManager::ReadSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs)
   463 TInt DSwapManager::ReadSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs)
   465 	{
   464 	{
   466 	__ASSERT_CRITICAL;
   465 	__ASSERT_CRITICAL;
   467 	
   466 	
       
   467 	TInt r = KErrNone;
   468 	const TUint readUnitShift = iDevice->iReadUnitShift;
   468 	const TUint readUnitShift = iDevice->iReadUnitShift;
   469 	TUint readSize = KPageSize >> readUnitShift;
   469 	TUint readSize = KPageSize >> readUnitShift;
   470 	TThreadMessage message;
   470 	TThreadMessage message;
   471 
   471 
   472 	const TUint indexEnd = aIndex + aCount;
   472 	const TUint indexEnd = aIndex + aCount;
   475 		START_PAGING_BENCHMARK;
   475 		START_PAGING_BENCHMARK;
   476 
   476 
   477 		MmuLock::Lock();	// MmuLock required for atomic access to manager data.
   477 		MmuLock::Lock();	// MmuLock required for atomic access to manager data.
   478 		TUint swapData = aMemory->PagingManagerData(index);
   478 		TUint swapData = aMemory->PagingManagerData(index);
   479 		TSwapState state = SwapState(swapData);
   479 		TSwapState state = SwapState(swapData);
   480 		TUint swapPage = SwapIndex(swapData);
       
   481 
   480 
   482 		if (state == EStateUnreserved)
   481 		if (state == EStateUnreserved)
   483 			{
   482 			{// This page is not committed to the memory object
   484 			// This page is not committed to the memory object
       
   485 			MmuLock::Unlock();
   483 			MmuLock::Unlock();
   486 			return KErrNotFound;			
   484 			return KErrNotFound;			
   487 			}
   485 			}
   488 		else if (state == EStateBlank)
   486 		else if (state == EStateBlank)
   489 			{
   487 			{// This page has not been written to yet so don't read from swap 
   490 			if (swapPage != 0)
   488 			// just wipe it if required.
       
   489 			TUint allocFlags = aMemory->RamAllocFlags();
       
   490 			MmuLock::Unlock();
       
   491 			TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
       
   492 			if (wipePages)
   491 				{
   493 				{
   492 				// An error occured while writing the page out, so report it now
   494 				TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ?
   493 				MmuLock::Unlock();
   495 					(allocFlags >> Mmu::EAllocWipeByteShift) & 0xff :
   494 				return -swapPage; 
   496 					0x03;
   495 				}
   497 				memset((TAny*)aLinAddr, wipeByte, KPageSize);
   496 			else
       
   497 				{
       
   498 				// This page has not been written to yet so don't read from swap 
       
   499 				// just wipe it if required.
       
   500 				TUint allocFlags = aMemory->RamAllocFlags();
       
   501 				MmuLock::Unlock();
       
   502 				TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
       
   503 				if (wipePages)
       
   504 					{
       
   505 					TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ?
       
   506 						(allocFlags >> Mmu::EAllocWipeByteShift) & 0xff :
       
   507 						0x03;
       
   508 					memset((TAny*)aLinAddr, wipeByte, KPageSize);
       
   509 					}
       
   510 				}
   498 				}
   511 			}
   499 			}
   512 		else
   500 		else
   513 			{
   501 			{
   514 			// It is not possible to get here if the page is in state EStateWriting as if so it must
   502 			// It is not possible to get here if the page is in state EStateWriting as if so it must
   516 			__NK_ASSERT_DEBUG(state == EStateWritten);
   504 			__NK_ASSERT_DEBUG(state == EStateWritten);
   517 			
   505 			
   518 			// OK to release as if the object's data is decommitted the pager 
   506 			// OK to release as if the object's data is decommitted the pager 
   519 			// will check that data is still valid before mapping it.
   507 			// will check that data is still valid before mapping it.
   520 			MmuLock::Unlock();
   508 			MmuLock::Unlock();
   521 			TUint readStart = (swapPage << KPageShift) >> readUnitShift;
   509 			TUint readStart = (SwapIndex(swapData) << KPageShift) >> readUnitShift;
   522 			START_PAGING_BENCHMARK;
   510 			START_PAGING_BENCHMARK;
   523 			TInt r = iDevice->Read(&message, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
   511 			r = iDevice->Read(&message, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
       
   512 			if (r != KErrNone)
       
   513 				__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::ReadSwapPages: error reading media at %08x + %x: %d", readStart << readUnitShift, readSize << readUnitShift, r));				
       
   514 			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
   524 			END_PAGING_BENCHMARK(EPagingBmReadDataMedia);
   515 			END_PAGING_BENCHMARK(EPagingBmReadDataMedia);
   525 			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore shouldn't fail with KErrNoMemory
   516 			__NK_ASSERT_ALWAYS(r == KErrNone);
   526 			if (r != KErrNone)
       
   527 				__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::ReadSwapPages: error reading media at %08x + %x: %d", readStart << readUnitShift, readSize << readUnitShift, r));
       
   528 			r = ThePager.EmbedErrorContext(EPagingErrorContextDataRead, r);
       
   529 			if (r != KErrNone)
       
   530 				return r;
       
   531 			}
   517 			}
   532 		END_PAGING_BENCHMARK(EPagingBmReadDataPage);
   518 		END_PAGING_BENCHMARK(EPagingBmReadDataPage);
   533 		}
   519 		}
   534 	
   520 
   535 	return KErrNone;
   521 	return r;
   536 	}
   522 	}
   537 
   523 
   538 
   524 
   539 /**
   525 /**
   540 Write the specified memory object's pages from the RAM into the swap.
   526    Write the specified memory object's pages from the RAM into the swap.
   541 
   527 
   542 @param	aMemory		The memory object who owns the pages.
   528    @param	aMemory		The memory object who owns the pages.
   543 @param	aIndex		The index within the memory object.
   529    @param	aIndex		The index within the memory object.
   544 @param 	aCount		The number of pages to write out.
   530    @param 	aCount		The number of pages to write out.
   545 @param	aLinAddr	The location of the pages to write out.
   531    @param	aLinAddr	The location of the pages to write out.
   546 @param  aBackground Whether this is being called in the background by the page cleaning thread
   532    @param  aBackground Whether this is being called in the background by the page cleaning thread
   547                     as opposed to on demand when a free page is required.
   533    as opposed to on demand when a free page is required.
   548 
   534 
   549 @pre Called with page cleaning lock held
   535    @pre Called with page cleaning lock held
   550 */
   536 */
   551 TInt DSwapManager::WriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs, TBool aBackground)
   537 TInt DSwapManager::WriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TPhysAddr* aPhysAddrs, TBool aBackground)
   552 	{
   538 	{
   553 	TRACE(("DSwapManager::WriteSwapPages %d pages", aCount));
   539 	TRACE(("DSwapManager::WriteSwapPages %d pages", aCount));
   554 	
   540 	
   638 	TInt r;
   624 	TInt r;
   639 	if (aLinAddr == 0)
   625 	if (aLinAddr == 0)
   640 		r = iDevice->WritePhysical(&msg, aPhysAddrs, aCount, writeOffset, aBackground);
   626 		r = iDevice->WritePhysical(&msg, aPhysAddrs, aCount, writeOffset, aBackground);
   641 	else
   627 	else
   642 		r = iDevice->Write(&msg, aLinAddr + (aPageIndex << KPageShift), writeOffset, writeSize, aBackground);
   628 		r = iDevice->Write(&msg, aLinAddr + (aPageIndex << KPageShift), writeOffset, writeSize, aBackground);
   643 	END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
       
   644 		
   629 		
   645 	if (r != KErrNone)
   630 	if (r != KErrNone)
   646 		{
   631 		{
   647 		__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::WriteSwapPages: error writing media from %08x to %08x + %x: %d", aLinAddr, writeOffset << readUnitShift, writeSize << readUnitShift, r));
   632 		__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::WriteSwapPages: error writing media from %08x to %08x + %x: %d", aLinAddr, writeOffset << readUnitShift, writeSize << readUnitShift, r));
   648 		if (r > 0)
       
   649 			r = KErrGeneral;
       
   650 		}
   633 		}
   651 	__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
   634 	__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
   652 	r = ThePager.EmbedErrorContext(EPagingErrorContextDataWrite, r); 
   635 	__NK_ASSERT_ALWAYS(r == KErrNone);
       
   636 	END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
   653 
   637 
   654 	TUint i;
   638 	TUint i;
   655 	TUint swapData[KMaxPagesToClean];
   639 	TUint swapData[KMaxPagesToClean];
   656 	
   640 	
   657 	MmuLock::Lock();
   641 	MmuLock::Lock();
   661 		swapData[i] = aMemory[i]->PagingManagerData(aIndex[i]);
   645 		swapData[i] = aMemory[i]->PagingManagerData(aIndex[i]);
   662 		TSwapState s = SwapState(swapData[i]);
   646 		TSwapState s = SwapState(swapData[i]);
   663 		__NK_ASSERT_DEBUG(s == EStateUnreserved || s == EStateWriting);
   647 		__NK_ASSERT_DEBUG(s == EStateUnreserved || s == EStateWriting);
   664 		if (s == EStateWriting)
   648 		if (s == EStateWriting)
   665 			{
   649 			{
   666 			// Store the new swap location and mark the page as saved, or if an error occured then
   650 			// Store the new swap location and mark the page as saved.
   667 			// record the error code instead
   651 			aMemory[i]->SetPagingManagerData(aIndex[i], SwapData(EStateWritten, aSwapIndex + i));
   668 			TUint swapData = (r == KErrNone) 
       
   669 				? SwapData(EStateWritten, aSwapIndex + i)
       
   670 				: SwapData(EStateBlank, -r);
       
   671 			aMemory[i]->SetPagingManagerData(aIndex[i], swapData);
       
   672 			}
   652 			}
   673 		}
   653 		}
   674 	MmuLock::Unlock();
   654 	MmuLock::Unlock();
   675 
   655 
   676 	for (i = 0 ; i < aCount ; ++i)
   656 	for (i = 0 ; i < aCount ; ++i)
   677 		{
   657 		{
   678 		TSwapState s = SwapState(swapData[i]);
   658 		TSwapState s = SwapState(swapData[i]);
   679 		if (s == EStateUnreserved || s == EStateBlank)
   659 		if (s == EStateUnreserved)
   680 			{
   660 			{
   681 			// The page was either decommitted while we were cleaning it, or an error occured while
   661 			// The page was decommitted while we were cleaning it, so free the swap page we
   682 			// writing.  Free the swap page and don't modify the state.
   662 			// allocated and continue, leaving this page in the unreserved state.
   683 			FreeSwapIndex(aSwapIndex + i);
   663 			FreeSwapIndex(aSwapIndex + i);
   684 			}
   664 			}
   685 		}
   665 		}
   686 
   666 
   687 	// write errors are not reported at this point as this will just kill a thread unrelated to the
   667 	return KErrNone;
   688 	// one whose data has been lost
       
   689 	return KErrNone;  
       
   690 	}
   668 	}
   691 	
   669 	
   692 
   670 
   693 /**
   671 /**
   694 Notify the media driver that the page written to swap is no longer required.
   672 Notify the media driver that the page written to swap is no longer required.