diff -r 000000000000 -r a41df078684a kerneltest/e32test/defrag/d_pagemove.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/defrag/d_pagemove.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,502 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\defrag\d_pagemove.cpp +// LDD for testing defrag page moving +// +// + +#include +#include "platform.h" +#include "d_pagemove.h" +#include "nk_priv.h" + +// debug tracing for this test driver is very noisy - off by default +#undef DEBUG_PAGEMOVE +#ifdef DEBUG_PAGEMOVE +#define DBG(a) a +#else +#define DBG(a) +#endif + +const TInt KArbitraryNumber = 4; + +// This driver is ram loaded (see mmp file) so this function will do fine +// as a test of RAM-loaded code. +TInt RamLoadedFunction() + { + return KArbitraryNumber; + } + +const TInt KMajorVersionNumber=0; +const TInt KMinorVersionNumber=1; +const TInt KBuildVersionNumber=1; + + +_LIT(KLddName,"PageMove"); + +class DPageMove; + +class DPageMoveFactory : public DLogicalDevice +// +// Page move LDD factory +// + { +public: + DPageMoveFactory(); + virtual TInt Install(); //overriding pure virtual + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual + }; + +class DPageMove : public DLogicalChannelBase +// +// Page move logical channel +// + { +public: + DPageMove(); + ~DPageMove(); +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); + TInt DoPageMove(TLinAddr aAddr, TBool aEchoOff=EFalse); + TInt KernelDataMovePerformance(void); + TInt iPageSize; + }; + +DECLARE_STANDARD_LDD() + { + return new DPageMoveFactory; + } + +DPageMoveFactory::DPageMoveFactory() +// +// Constructor +// + { + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + //iParseMask=0;//No units, no info, no PDD + //iUnitsMask=0;//Only one thing + } + +TInt DPageMoveFactory::Create(DLogicalChannelBase*& aChannel) +// +// Create a new DPageMove on this logical device +// + { + aChannel=new DPageMove; + return aChannel?KErrNone:KErrNoMemory; + } + +TInt DPageMoveFactory::Install() +// +// Install the LDD - overriding pure virtual +// + { + return SetName(&KLddName); + } + +void DPageMoveFactory::GetCaps(TDes8& aDes) const +// +// Get capabilities - overriding pure virtual +// + { + TCapsPageMoveV01 b; + b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); + } + +DPageMove::DPageMove() +// +// Constructor +// + { + } + +TInt DPageMove::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) +// +// Create channel +// + { + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) + return KErrNotSupported; + iPageSize=Kern::RoundToPageSize(1); + return KErrNone; + } + +DPageMove::~DPageMove() +// +// Destructor +// + { + } + +TInt DPageMove::Request(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + DBG(Kern::Printf("DPageMove::Request func=%d a1=%08x a2=%08x", aFunction, a1, a2)); + NKern::ThreadEnterCS(); + switch (aFunction) + { + case RPageMove::EControlTryMovingKHeap: + // Allocate a large array on the kernel heap and try moving it around. + { + const TInt size=16384; + TUint8* array = new TUint8[size]; + if (array == NULL) + r=KErrNoMemory; + else + { + for (TInt i=0; i 0; i--) + { + while (pageAddr < endAddr) + { + r = DoPageMove(pageAddr); + + if (r != KErrNone) + { + goto exit; + } + pageAddr += iPageSize; + } + pageAddr = baseAddr; + } + endTime = NKern::FastCounter(); + break; + } + diff = endTime - startTime; + if (endTime < startTime) + { + Kern::Printf("WARNING - fast counter overflowed. Assuming only once and continuing"); + diff = (KMaxTUint32 - startTime) + endTime; + } + + if (diff == 0) + { + Kern::Printf("difference 0!"); + tot--; + } + + if (diff > maxTime) + maxTime = diff; + if (diff < minTime) + minTime = diff; + + if (cummulative + diff < cummulative) + { + Kern::Printf("OverFlow!!!"); + r = KErrOverflow; + goto exit; + } + pageAddr = baseAddr; + cummulative += diff; + } + switch (moveMode) + { + case EKMoveHeap: + if (tot != 0) + { + TUint average = (cummulative / tot); + Kern::Printf("Fast counter ticks to move %d kernel heap pages: Av %d Min %d Max %d (non zero iterations = %d out of %d)", pagesMoved, average, minTime, maxTime, tot, KMoveAttempts); + Kern::Printf("Average of %d ticks to move one page\n", average / pagesMoved); + } + else + Kern::Printf("WARNING - all kernel heap page moves took 0 fast counter ticks"); + break; + + case EKMoveStack: + if (tot != 0) + { + TUint average = (cummulative / tot); + Kern::Printf("Fast counter ticks to move %d kernel stack pages %d times: Av %d Min %d Max %d (non zero iterations = %d out of %d)", pagesMoved, actualHeapPages, average, minTime, maxTime, tot, KMoveAttempts); + Kern::Printf("Average of %d ticks to move one page\n", average / (pagesMoved * actualHeapPages)); + } + else + Kern::Printf("WARNING - all kernel stack page moves took 0 fast counter ticks"); + break; + } + } + + r = KErrNone; +exit: + delete [] heapArray; + return r; + } + +