kernel/eka/memmodel/epoc/flexible/mmu/mpager.h
changeset 259 57b9594f5772
parent 201 43365a9b78a3
equal deleted inserted replaced
247:d8d70de2bd36 259:57b9594f5772
   416 
   416 
   417 	@param aCleanInSequence  Whether pages must have sequential page colour
   417 	@param aCleanInSequence  Whether pages must have sequential page colour
   418 	*/
   418 	*/
   419 	void SetCleanInSequence(TBool aCleanInSequence);
   419 	void SetCleanInSequence(TBool aCleanInSequence);
   420 
   420 
       
   421 	/**
       
   422 	Generate a new error code that includes both the original error code and some extra context
       
   423 	information.  This is used to communicate context information from where it occurs to where it
       
   424 	is handled.
       
   425 	*/
       
   426 	TInt EmbedErrorContext(TPagingErrorContext aContext, TInt aError);
       
   427 
       
   428 	/**
       
   429 	Extract the context information from a error code generated by #EmbedErrorContext.
       
   430 	*/
       
   431 	static TPagingErrorContext ExtractErrorContext(TInt aContextError);
       
   432 
       
   433 	/**
       
   434 	Extract the original error code from a error code generated by #EmbedErrorContext.
       
   435 	*/
       
   436 	static TInt ExtractErrorCode(TInt aContextError);
       
   437 
   421 private:
   438 private:
   422 	/**
   439 	/**
   423 	Add a page to the head of the live page list. I.e. make it the 'youngest' page.
   440 	Add a page to the head of the live page list. I.e. make it the 'youngest' page.
   424 
   441 
   425 	@pre MmuLock held
   442 	@pre MmuLock held
   638 	@return True if operation was successful.
   655 	@return True if operation was successful.
   639 	*/
   656 	*/
   640 	TBool ReservePage();
   657 	TBool ReservePage();
   641 
   658 
   642 	/**
   659 	/**
       
   660 	Determine the thread responsible for this page fault.  This returns either NULL to indicate
       
   661 	the current thread, or a remote thread if the fault is caused by an IPC operation.
       
   662 	*/
       
   663 	DThread* ResponsibleThread(DThread* aThread, TAny* aExceptionInfo);
       
   664 
       
   665 	/**
   643 	Called when a realtime thread takes a paging fault.
   666 	Called when a realtime thread takes a paging fault.
   644 	Checks whether it's OK for the thread to take to fault.
   667 	Checks whether it's OK for the thread to take to fault.
   645 	@return KErrNone if the paging fault should be further processed
   668 	@return KErrNone if the paging fault should be further processed
   646 	*/
   669 	*/
   647 	TInt CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo);
   670 	TInt CheckRealtimeThreadFault(DThread* aThread, TAny* aExceptionInfo);
       
   671 	
       
   672 	/**
       
   673 	Kills the thread responsible for causing a page fault.
       
   674 
       
   675 	This is called when a fatal error is encountered when handling a page fault, for example, if a
       
   676 	media access fails.
       
   677 
       
   678 	Originally the paging system reacted by faulting the system in such cases.  However the current
       
   679 	approach was thought to be preferable as this kind of error can happen in practice (even though
       
   680 	in theory it should not) and it means that the error code is reported and can be captured by
       
   681 	MobileCrash.
       
   682 	*/
       
   683 	void KillResponsibleThread(TPagingErrorContext aErrorCategory, TInt aErrorCode,
       
   684 							   TAny* aExceptionInfo);
   648 	
   685 	
   649 	/**
   686 	/**
   650 	Attempt to find the page table entry and page info for a page in the specified mapping.
   687 	Attempt to find the page table entry and page info for a page in the specified mapping.
   651 
   688 
   652 	@param aOsAsid				The OsAsid of the process that owns the mapping.
   689 	@param aOsAsid				The OsAsid of the process that owns the mapping.
   706 	void ResetBenchmarkData(TPagingBenchmark aBm);
   743 	void ResetBenchmarkData(TPagingBenchmark aBm);
   707 	void ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut);
   744 	void ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut);
   708 	TSpinLock iBenchmarkLock;
   745 	TSpinLock iBenchmarkLock;
   709 	SPagingBenchmarkInfo iBenchmarkInfo[EMaxPagingBm];
   746 	SPagingBenchmarkInfo iBenchmarkInfo[EMaxPagingBm];
   710 #endif //__DEMAND_PAGING_BENCHMARKS__
   747 #endif //__DEMAND_PAGING_BENCHMARKS__
       
   748 
       
   749 #ifdef _DEBUG
       
   750 	TPagingErrorContext iDebugFailContext;
       
   751 #endif
   711 	};
   752 	};
   712 
   753 
   713 extern DPager ThePager;
   754 extern DPager ThePager;
       
   755 
       
   756 
       
   757 // Functions to embed context information into error codes, using the following scheme:
       
   758 //
       
   759 // bits 0-16   taken from original error code
       
   760 // bits 16-31  bitwise NOT of a TPagingErrorContext value
       
   761 //
       
   762 // Since the context informtion is a small positive integer, the resulting error code is still a
       
   763 // negative integer.  The value EPagingErrorContextNone is zero, yeilding the original error code
       
   764 // unchanged if embedded.
       
   765 
       
   766 inline TInt DPager::EmbedErrorContext(TPagingErrorContext aContext, TInt aError)
       
   767 	{
       
   768 	__NK_ASSERT_DEBUG(aContext > 0 && aContext <= 0x7fff);
       
   769 #ifdef _DEBUG
       
   770 	if (aError >= KErrNone)
       
   771 		{
       
   772 		TUint32 match = aContext;
       
   773 		if (__e32_atomic_cas_ord32(&iDebugFailContext, &match, 0))
       
   774 			aError = KErrAbort;
       
   775 		}
       
   776 #endif
       
   777 	if (aError >= KErrNone)
       
   778 		return aError;
       
   779 	if (aError < (TInt)0xffff0000)
       
   780 		aError = KErrGeneral;  // lose error code, but doesn't happen in practice
       
   781 	return (aError & 0x0000ffff) | ((~aContext) << 16);
       
   782 	}
       
   783 
       
   784 inline TPagingErrorContext DPager::ExtractErrorContext(TInt aContextError)
       
   785 	{
       
   786 	return (TPagingErrorContext)((~aContextError) >> 16);
       
   787 	}
       
   788 
       
   789 inline TInt DPager::ExtractErrorCode(TInt aContextError)
       
   790 	{
       
   791 	return aContextError | 0x7fff000;
       
   792 	}
   714 
   793 
   715 
   794 
   716 #ifdef __DEMAND_PAGING_BENCHMARKS__
   795 #ifdef __DEMAND_PAGING_BENCHMARKS__
   717 
   796 
   718 #define START_PAGING_BENCHMARK TUint32 _bmStart = NKern::FastCounter()
   797 #define START_PAGING_BENCHMARK TUint32 _bmStart = NKern::FastCounter()
  1011 	Called by DPager::Init3().
  1090 	Called by DPager::Init3().
  1012 	*/
  1091 	*/
  1013 	static void Init();	
  1092 	static void Init();	
  1014 	};
  1093 	};
  1015 
  1094 
  1016 
       
  1017 #endif
  1095 #endif