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() |