Changeset 38956 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Oct 6, 2011 12:43:01 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r38955 r38956 3703 3703 /* Age compression - ASSUMES iNow == 4. */ 3704 3704 PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode; 3705 if (pChunk->i Age>= UINT32_C(0xffffff00))3706 pChunk->i Age= 3;3707 else if (pChunk->i Age>= UINT32_C(0xfffff000))3708 pChunk->i Age= 2;3709 else if (pChunk->i Age)3710 pChunk->i Age= 1;3711 else /* i Age= 0 */3712 pChunk->i Age= 4;3705 if (pChunk->iLastUsed >= UINT32_C(0xffffff00)) 3706 pChunk->iLastUsed = 3; 3707 else if (pChunk->iLastUsed >= UINT32_C(0xfffff000)) 3708 pChunk->iLastUsed = 2; 3709 else if (pChunk->iLastUsed) 3710 pChunk->iLastUsed = 1; 3711 else /* iLastUsed = 0 */ 3712 pChunk->iLastUsed = 4; 3713 3713 return 0; 3714 }3715 3716 3717 /**3718 * Tree enumeration callback that updates the chunks that have3719 * been used since the last3720 */3721 static DECLCALLBACK(int) pgmR3PhysChunkAgeingCallback(PAVLU32NODECORE pNode, void *pvUser)3722 {3723 PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;3724 if (!pChunk->iAge)3725 {3726 PVM pVM = (PVM)pvUser;3727 pChunk->iAge = pVM->pgm.s.ChunkR3Map.iNow;3728 }3729 return 0;3730 }3731 3732 3733 /**3734 * Performs ageing of the ring-3 chunk mappings.3735 *3736 * @param pVM The VM handle.3737 */3738 VMMR3DECL(void) PGMR3PhysChunkAgeing(PVM pVM)3739 {3740 pgmLock(pVM);3741 pVM->pgm.s.ChunkR3Map.AgeingCountdown = RT_MIN(pVM->pgm.s.ChunkR3Map.cMax / 4, 1024);3742 pVM->pgm.s.ChunkR3Map.iNow++;3743 if (pVM->pgm.s.ChunkR3Map.iNow == 0)3744 {3745 pVM->pgm.s.ChunkR3Map.iNow = 4;3746 RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, pVM);3747 }3748 else3749 RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingCallback, pVM);3750 pgmUnlock(pVM);3751 3714 } 3752 3715 … … 3759 3722 PVM pVM; /**< The VM handle. */ 3760 3723 PPGMCHUNKR3MAP pChunk; /**< The chunk to unmap. */ 3761 uint32_t iLastAge; /**< Highest age found so far. */3762 3724 } PGMR3PHYSCHUNKUNMAPCB, *PPGMR3PHYSCHUNKUNMAPCB; 3763 3725 … … 3773 3735 3774 3736 /* 3775 * Check for locks and age.3737 * Check for locks and compare when last used. 3776 3738 */ 3777 3739 if (pChunk->cRefs) 3778 3740 return 0; 3779 if ( !pChunk->iAge)3741 if (pChunk->cPermRefs) 3780 3742 return 0; 3781 if (pArg->iLastAge >= pChunk->iAge) 3743 if ( pArg->pChunk 3744 && pChunk->iLastUsed >= pArg->pChunk->iLastUsed) 3782 3745 return 0; 3783 3746 … … 3804 3767 return 0; 3805 3768 3806 pArg->pChunk = pChunk; 3807 pArg->iLastAge = pChunk->iAge; 3769 pArg->pChunk = pChunk; 3808 3770 return 0; 3809 3771 } … … 3824 3786 3825 3787 /* 3826 * Do tree ageing first?3827 */3828 if (pVM->pgm.s.ChunkR3Map.AgeingCountdown-- == 0)3829 {3830 STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);3831 PGMR3PhysChunkAgeing(pVM);3832 STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkAging, a);3833 }3834 3835 /*3836 3788 * Enumerate the age tree starting with the left most node. 3837 3789 */ 3838 3790 STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkFindCandidate, a); 3839 3791 PGMR3PHYSCHUNKUNMAPCB Args; 3840 Args.pVM = pVM; 3841 Args.pChunk = NULL; 3842 Args.iLastAge = 0; 3792 Args.pVM = pVM; 3793 Args.pChunk = NULL; 3843 3794 RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkUnmapCandidateCallback, &Args); 3844 3795 Assert(Args.pChunk); … … 3983 3934 3984 3935 /* 3936 * Move the chunk time forward. 3937 */ 3938 pVM->pgm.s.ChunkR3Map.iNow++; 3939 if (pVM->pgm.s.ChunkR3Map.iNow == 0) 3940 { 3941 pVM->pgm.s.ChunkR3Map.iNow = 4; 3942 RTAvlU32DoWithAll(&pVM->pgm.s.ChunkR3Map.pTree, true /*fFromLeft*/, pgmR3PhysChunkAgeingRolloverCallback, NULL); 3943 } 3944 3945 /* 3985 3946 * Allocate a new tracking structure first. 3986 3947 */ … … 3991 3952 #endif 3992 3953 AssertReturn(pChunk, VERR_NO_MEMORY); 3993 pChunk->Core.Key = idChunk; 3954 pChunk->Core.Key = idChunk; 3955 pChunk->iLastUsed = pVM->pgm.s.ChunkR3Map.iNow; 3994 3956 3995 3957 /* … … 3998 3960 GMMMAPUNMAPCHUNKREQ Req; 3999 3961 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC; 4000 Req.Hdr.cbReq = sizeof(Req);4001 Req.pvR3 = NULL;4002 Req.idChunkMap = idChunk;3962 Req.Hdr.cbReq = sizeof(Req); 3963 Req.pvR3 = NULL; 3964 Req.idChunkMap = idChunk; 4003 3965 Req.idChunkUnmap = NIL_GMM_CHUNKID; 4004 3966 … … 4009 3971 if (RT_SUCCESS(rc)) 4010 3972 { 3973 pChunk->pv = Req.pvR3; 3974 4011 3975 /* 4012 3976 * If we're running out of virtual address space, then we should … … 4053 4017 * the chunk we're going to return isn't unmapped by accident. 4054 4018 */ 4055 /* insert the new one. */4056 4019 AssertPtr(Req.pvR3); 4057 pChunk->pv = Req.pvR3;4058 4020 bool fRc = RTAvlU32Insert(&pVM->pgm.s.ChunkR3Map.pTree, &pChunk->Core); 4059 4021 AssertRelease(fRc);
Note:
See TracChangeset
for help on using the changeset viewer.