150 This reduces the live page list to a minimum. |
150 This reduces the live page list to a minimum. |
151 */ |
151 */ |
152 void FlushAll(); |
152 void FlushAll(); |
153 |
153 |
154 /** |
154 /** |
|
155 Flush demand paged pages in a specified region. |
|
156 |
|
157 The memory must reside in a single memory object. |
|
158 |
|
159 @param aProcess The process containing the pages to flush. |
|
160 @param aStart The start address of the region. |
|
161 @param aSize The size of the region in bytes. |
|
162 |
|
163 @return KErrBadDescriptor If the memory region is invalid or spans more than one memory object, |
|
164 otherwise KErrNone. |
|
165 */ |
|
166 TInt FlushRegion(DMemModelProcess* aProcess, TLinAddr aStartAddress, TUint aSize); |
|
167 |
|
168 /** |
155 Give pages to paging system for managing. |
169 Give pages to paging system for managing. |
156 */ |
170 */ |
157 void DonatePages(TUint aCount, TPhysAddr* aPages); |
171 void DonatePages(TUint aCount, TPhysAddr* aPages); |
158 |
172 |
159 /** |
173 /** |
402 |
416 |
403 @param aCleanInSequence Whether pages must have sequential page colour |
417 @param aCleanInSequence Whether pages must have sequential page colour |
404 */ |
418 */ |
405 void SetCleanInSequence(TBool aCleanInSequence); |
419 void SetCleanInSequence(TBool aCleanInSequence); |
406 |
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 |
407 private: |
438 private: |
408 /** |
439 /** |
409 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. |
410 |
441 |
411 @pre MmuLock held |
442 @pre MmuLock held |
624 @return True if operation was successful. |
655 @return True if operation was successful. |
625 */ |
656 */ |
626 TBool ReservePage(); |
657 TBool ReservePage(); |
627 |
658 |
628 /** |
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 /** |
629 Called when a realtime thread takes a paging fault. |
666 Called when a realtime thread takes a paging fault. |
630 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. |
631 @return KErrNone if the paging fault should be further processed |
668 @return KErrNone if the paging fault should be further processed |
632 */ |
669 */ |
633 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); |
634 |
685 |
635 /** |
686 /** |
636 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. |
637 |
688 |
638 @param aOsAsid The OsAsid of the process that owns the mapping. |
689 @param aOsAsid The OsAsid of the process that owns the mapping. |
692 void ResetBenchmarkData(TPagingBenchmark aBm); |
743 void ResetBenchmarkData(TPagingBenchmark aBm); |
693 void ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut); |
744 void ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut); |
694 TSpinLock iBenchmarkLock; |
745 TSpinLock iBenchmarkLock; |
695 SPagingBenchmarkInfo iBenchmarkInfo[EMaxPagingBm]; |
746 SPagingBenchmarkInfo iBenchmarkInfo[EMaxPagingBm]; |
696 #endif //__DEMAND_PAGING_BENCHMARKS__ |
747 #endif //__DEMAND_PAGING_BENCHMARKS__ |
|
748 |
|
749 #ifdef _DEBUG |
|
750 TPagingErrorContext iDebugFailContext; |
|
751 #endif |
697 }; |
752 }; |
698 |
753 |
699 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 } |
700 |
793 |
701 |
794 |
702 #ifdef __DEMAND_PAGING_BENCHMARKS__ |
795 #ifdef __DEMAND_PAGING_BENCHMARKS__ |
703 |
796 |
704 #define START_PAGING_BENCHMARK TUint32 _bmStart = NKern::FastCounter() |
797 #define START_PAGING_BENCHMARK TUint32 _bmStart = NKern::FastCounter() |