diff -r 0ff03867bdb6 -r 39b39e1a406e kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp --- a/kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp Wed Jul 21 14:46:58 2010 +0100 +++ b/kernel/eka/memmodel/epoc/flexible/mmu/mdefrag.cpp Thu Jul 22 16:46:39 2010 +0100 @@ -115,51 +115,89 @@ RamAllocLock::Lock(); // Move the page to any RAM zone. - r = M::MovePage(aOld, aNew, KRamZoneInvalidId, EFalse); + r = M::MovePage(aOld, aNew, KRamZoneInvalidId, 0); RamAllocLock::Unlock(); return r; } -TInt M::MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest) +TInt M::MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TUint aMoveDisFlags) { - TInt r; + // Returns this when page is not paged or managed or free but is a real RAM page. + TInt r = KErrNotSupported; // get memory object corresponding to the page... DMemoryObject* memory = 0; MmuLock::Lock(); - SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aOld&~KPageMask); + SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aOld & ~KPageMask); + if (pi) + { + if (pi->PagedState() != SPageInfo::EUnpaged) + {// The page is paged so let the pager handle it. + return ThePager.DiscardPage(pi, aBlockZoneId, aMoveDisFlags); + } + switch (pi->Type()) + { + case SPageInfo::EManaged: + memory = pi->Owner(); + memory->Open(); + // move page, this will release the mmu lock. + r = memory->iManager->MovePage( memory, pi, aNew, aBlockZoneId, + (aMoveDisFlags & M::EMoveDisBlockRest)!=0); + memory->AsyncClose(); + break; + case SPageInfo::EUnused: + r = KErrNotFound; // This page is free so nothing to do. + // Fall through.. + default: + MmuLock::Unlock(); + } + } + else + {// page info for aOld not found so aOld is not a RAM page... + MmuLock::Unlock(); + r = KErrArgument; + } + return r; + } + + +TInt M::MoveAndAllocPage(TPhysAddr aAddr, TZonePageType aPageType) + { + // Returns this when page is not paged or managed or free but is a real RAM page. + TInt r = KErrNotSupported; + + // get memory object corresponding to the page... + DMemoryObject* memory = 0; + MmuLock::Lock(); + SPageInfo* pi = SPageInfo::SafeFromPhysAddr(aAddr & ~KPageMask); if(pi) { if (pi->PagedState() != SPageInfo::EUnpaged) {// The page is paged so let the pager handle it. - return ThePager.DiscardPage(pi, aBlockZoneId, aBlockRest); + return ThePager.DiscardAndAllocPage(pi, aPageType); } - if (pi->Type()==SPageInfo::EManaged) - memory = pi->Owner(); - } - MmuLock::Unlock(); - - // Note, whilst we hold the RamAllocLock the page can't change it's use - // and we can safely assume that it still belongs to the memory object - // at a fixed page index. - // Also, as memory objects can't be destroyed whilst they still own pages - // we can safely access this object without taking an explicit referernce, - // i.e. we don't need to Open() the memory object. - if (!pi) - {// page info for aOld not found so aOld is not a RAM page... - r = KErrArgument; - } - else if(!memory) - { - // page does not have a memory manager, so we can't move it... - r = KErrNotSupported; + switch (pi->Type()) + { + case SPageInfo::EManaged: + memory = pi->Owner(); + memory->Open(); + // move page, this will release the mmu lock. + r = memory->iManager->MoveAndAllocPage(memory, pi, aPageType); + memory->AsyncClose(); + break; + case SPageInfo::EUnused: + r = KErrNone; // This page is free so nothing to do. + // Fall through.. + default: + MmuLock::Unlock(); + } } else - { - // move page... - r = memory->iManager->MovePage(memory, pi, aNew, aBlockZoneId, aBlockRest); + {// page info for aAddr not found so aAddr is not a RAM page... + MmuLock::Unlock(); + r = KErrArgument; } return r; }