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