--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/defrag/t_ramdefrag.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,9827 @@
+// Copyright (c) 2008-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\t_ramdefrag.cpp
+// RAM Defragmentation Functional Tests
+//
+//
+
+//#define RUN_ALL_TESTS // Uncomment to ensure that all tests are run regardless of test failures
+//#define DEBUG_VER // Uncomment for information output from tests
+
+
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+RTest test(_L("T_RAMDEFRAG"));
+#include <e32rom.h>
+#include <u32hal.h>
+#include <f32file.h>
+#include <f32dbg.h>
+#include <e32msgqueue.h>
+#include <e32math.h>
+#include <hal.h>
+#include "testdefs.h"
+
+
+#include <dptest.h>
+
+#include "t_ramdefrag.h"
+
+#define READ(a) ReadByte((volatile TUint8*)(a))
+
+
+#ifdef RUN_ALL_TESTS
+#define TEST_FAIL {gTestStepFailed++;}
+#define CLEANUP(a) {}
+#else
+#define TEST_FAIL {TestCleanup(); test(EFalse);}
+#define CLEANUP(a) {if (!gFailPrintPageInfo) \
+ { \
+ PrintPageInfo(); \
+ gFailPrintPageInfo = ETrue; \
+ } \
+ a;}
+#endif
+
+
+
+#define TEST_DRIVER_OPEN 1
+#define TEST_DRIVER_CLOSE 0
+
+#define BEST_MOVABLE 1
+#define BEST_DISCARDABLE 2
+#define BEST_FIXED 3
+
+#define Z_ALLOC_CONTIG 1
+#define Z_ALLOC_DISC 2
+
+LOCAL_D TUint gTestStarted = EFalse; // Used to ensure matching TestStart() and TestEnd().
+LOCAL_D TBool gPagedRom = ETrue; // Stores whether or not is a paged ROM
+LOCAL_D TInt gTestStepFailed = 0; // Stores the number of test steps failed
+LOCAL_D TBool gFailPrintPageInfo = EFalse; // Set to ETrue once CLEANUP has been invoked once.
+LOCAL_D TBool gFileCacheRun = EFalse; // Set to ETrue whe FSCaching tests have been run
+
+LOCAL_D TInt gRamSize; // The total RAM size in bytes
+LOCAL_D TInt gFreeRam; // The amount of free RAM available in bytes
+LOCAL_D TInt gPageSize; // The number of bytes per page
+LOCAL_D TUint gPageShift;
+#ifdef DEBUG_VER
+LOCAL_D TInt gRamUsed; // The amount of RAM used in bytes
+#endif
+LOCAL_D TInt gInitialRam; // The initial free RAM before a test starts
+LOCAL_D TInt gEndRam; // The end free RAM when a test finishes
+LOCAL_D TUint gOriginalMinCacheSize; // The original DP minSize
+LOCAL_D TUint gOriginalMaxCacheSize; // The original DP maxSize
+LOCAL_D TInt gTotalRamLost; // The total amount of RAM lost during the test
+
+LOCAL_D TUint gZoneCount = 0; // Number of zones
+LOCAL_D const TUint KInvalidZoneID = 0xffffffff; // Invalid value for a zone ID
+LOCAL_D STestPageCount gTotalPageCount;
+
+
+LOCAL_D struct SRamZoneConfig* gZoneConfigArray; // Contains the configurations of all the zones
+LOCAL_D struct SRamZoneUtilisation* gZoneUtilArray; // Contains the utilisations of all the zones
+LOCAL_D struct SRamZoneUtilisation* gOriginalPageCountArray; // Contains the original utilisations of the zones
+LOCAL_D TInt* gPrefArray; // Contains the preference order of the zones
+LOCAL_D TUint8* gOrigFlagArray; // Contains the orignal values for the zone flags
+
+LOCAL_D TInt gDefragMaxPages = 0;
+
+const TInt KFillAllMovable = -1;
+
+LOCAL_D RChunk* gChunkArray1 = NULL; // Stores reference to all the chunks that have been created
+LOCAL_D RChunk* gChunkArray2 = NULL; // Stores reference to all the chunks that have been created
+LOCAL_D TUint gChunkArraySize1 = 0; // The size of the array gChunkArray
+LOCAL_D TUint gChunkArraySize2 = 0; // The size of the array gChunkArray
+const TUint KChunkDefaultSize = 0x300000;
+const TUint KMaxChunks = 14;
+LOCAL_D const TUint KNumAllocChunks = 10; // The number of chunks to be allocd for some tests.
+
+LOCAL_D RRamDefragFuncTestLdd Ldd; // Main Ldd used to call into device driver
+
+LOCAL_D TBuf<20> gTestThreadName =_L("TestThread");
+LOCAL_D RThread gTestThread;
+LOCAL_D TRequestStatus status;
+
+LOCAL_D TInt gDrive; // The removable media drive
+LOCAL_D RFs gTheFs;
+LOCAL_D TFileName gSessionPath;
+
+const TInt KNoRemovableDrive = -1; // gDrive is set to this when no suitable drive can be found.
+const TInt KDefaultCacheSize = (128 + 12) * 1024; // The default file system cache size
+const TUint KNumFilesOrig = (32 * 1024 * 1024) / KDefaultCacheSize; // The number of files that are needed to fill the file system cache
+LOCAL_D TInt gFilesNeededToFillCache = KNumFilesOrig ; // Not constant as can change depending on the size of the disk
+LOCAL_D RFile gFile[KNumFilesOrig];
+
+LOCAL_D TInt* gCandList1; // Array of zones that have the same preference and the same
+LOCAL_D TInt* gCandList2; // amount of free pages
+const TInt KInvalidCandIndex = -1;
+
+//
+// GetDrive
+//
+// Gets the removable drive number
+//
+TInt GetDrive()
+ {
+ RFs theFs;
+ TInt r = theFs.Connect();
+ test_KErrNone(r);
+
+ TInt driveLet = KNoRemovableDrive;
+
+ TInt i = EDriveA;
+ for (; i <= EDriveZ; i++)
+ {
+ TVolumeInfo volInfo;
+ r = theFs.Volume(volInfo, i);
+ if (r == KErrNone)
+ {// This drive no. exists so determine if it is removable and
+ // formattable media.
+ if ((volInfo.iDrive.iDriveAtt & KDriveAttRemovable) &&
+ (volInfo.iDrive.iMediaAtt & KMediaAttFormattable))
+ {
+ driveLet = i;
+ break;
+ }
+ }
+ }
+ theFs.Close();
+ return driveLet;
+ }
+
+
+//
+// DeviceDriver
+//
+// Opens or closes the device driver used
+//
+TInt DeviceDriver(TInt aFunctionNum)
+ {
+ TInt r = 0;
+ switch (aFunctionNum)
+ {
+ case TEST_DRIVER_OPEN:
+ {
+ r = User::LoadLogicalDevice(KRamDefragFuncTestLddName);
+ test(r==KErrNone || r==KErrAlreadyExists);
+ r = Ldd.Open();
+ test_KErrNone(r);
+ }
+ break;
+
+ case TEST_DRIVER_CLOSE:
+ {
+ Ldd.Close();
+ r = User::FreeLogicalDevice(KRamDefragFuncTestLddName);
+ test_KErrNone(r);
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ return r;
+ }
+
+
+//
+// GetOriginalPageCount
+//
+// Obtains the orginal types of pages in each of the zones
+//
+void GetOriginalPageCount()
+ {
+ TUint index;
+ TInt ret = 0;
+ TESTDEBUG(test.Printf(_L("ram defrag : Get info about the zones\n")));
+ for (index = 0; index < gZoneCount; index ++)
+ {
+ ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&gOriginalPageCountArray[index]);
+ test(ret == KErrNone);
+ }
+ }
+
+
+//
+// PrintPageInfo
+//
+// Prints various page information to the screen
+//
+void PrintPageInfo()
+ {
+ test.Printf(_L("\nZONE CONFIGURATIONS:\n"));
+ for (TUint index = 0; index < gZoneCount; index ++)
+ {
+ TInt ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)index, (TAny*)&gZoneConfigArray[index]);
+ test(ret == KErrNone);
+ test.Printf(_L("config : id=0x%08x index=%-2d base=0x%08x end=0x%08x pages=0x%08x pref=%-2d flags=0x%x\n"),
+ gZoneConfigArray[index].iZoneId,gZoneConfigArray[index].iZoneIndex,
+ gZoneConfigArray[index].iPhysBase,gZoneConfigArray[index].iPhysEnd,
+ gZoneConfigArray[index].iPhysPages,gZoneConfigArray[index].iPref,gZoneConfigArray[index].iFlags);
+ }
+ test.Printf(_L("\nZONE UTILISATIONS:\n"));
+ for (TUint index = 0; index < gZoneCount; index ++)
+ {
+ TInt ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&gZoneUtilArray[index]);
+ test(ret == KErrNone);
+ test.Printf(_L("usage : id=0x%08x index=%-2d pref=%d pages=0x%08x free=0x%08x unknown=0x%08x fixed=0x%08x move=0x%08x discard=0x%08x other=0x%08x\n"),
+ gZoneUtilArray[index].iZoneId,gZoneUtilArray[index].iZoneIndex,gZoneConfigArray[index].iPref,
+ gZoneUtilArray[index].iPhysPages,gZoneUtilArray[index].iFreePages,
+ gZoneUtilArray[index].iAllocUnknown,gZoneUtilArray[index].iAllocFixed,gZoneUtilArray[index].iAllocMovable,
+ gZoneUtilArray[index].iAllocDiscardable,gZoneUtilArray[index].iAllocOther);
+ }
+ }
+
+
+//
+// GetAllPageInfo
+//
+// Get various different page information for all zones
+// Also updates the total page count
+//
+void GetAllPageInfo()
+ {
+ TInt ret = 0;
+ gTotalPageCount.iFreePages = 0;
+ gTotalPageCount.iUnknownPages = 0;
+ gTotalPageCount.iFixedPages = 0;
+ gTotalPageCount.iMovablePages = 0;
+ gTotalPageCount.iDiscardablePages = 0;
+ gTotalPageCount.iOtherPages = 0;
+
+ // now get the config of each of the zones.
+ TUint index;
+ TESTDEBUG(test.Printf(_L("ram defrag : Get info about the zones\n")));
+ for (index = 0; index < gZoneCount; index ++)
+ {
+ ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)index, (TAny*)&gZoneConfigArray[index]);
+ test(ret == KErrNone);
+
+ ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneUtilisation,(TAny*)index, (TAny*)&gZoneUtilArray[index]);
+ test(ret == KErrNone);
+
+ gTotalPageCount.iFreePages += gZoneUtilArray[index].iFreePages;
+ gTotalPageCount.iUnknownPages += gZoneUtilArray[index].iAllocUnknown;
+ gTotalPageCount.iFixedPages += gZoneUtilArray[index].iAllocFixed;
+ gTotalPageCount.iMovablePages += gZoneUtilArray[index].iAllocMovable;
+ gTotalPageCount.iDiscardablePages += gZoneUtilArray[index].iAllocDiscardable;
+ gTotalPageCount.iOtherPages += gZoneUtilArray[index].iAllocOther;
+ }
+ TESTDEBUG(test.Printf(_L("free=0x%x unknown=0x%x fixed=0x%x move=0x%x discard=0x%x other=0x%x\n"),
+ gTotalPageCount.iFreePages, gTotalPageCount.iUnknownPages, gTotalPageCount.iFixedPages,
+ gTotalPageCount.iMovablePages, gTotalPageCount.iDiscardablePages,gTotalPageCount.iOtherPages));
+
+ TESTDEBUG(PrintPageInfo());
+ }
+
+void RestoreRamZoneFlags()
+ {
+ GetAllPageInfo(); // Update the current set of RAM zone flag data.
+ for (TUint index=0; index < gZoneCount; index++)
+ {
+ TUint zoneDefragID = gZoneConfigArray[index].iZoneId;
+ Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ORIG_FLAG, gOrigFlagArray[index]);
+ }
+ }
+
+void ResetRamZoneFlags()
+ {
+ GetAllPageInfo(); // Update the current set of RAM zone flag data.
+ for (TUint index=0; index < gZoneCount; index++)
+ {
+ TUint zoneDefragID = gZoneConfigArray[index].iZoneId;
+ Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, RESET_FLAG);
+ }
+ }
+
+void RemoveChunkAlloc(RChunk*& aChunkArray, TUint& aChunkArraySize);
+void ResetDPCache();
+
+void FSCachCleanUp()
+ {
+ // If the File System Caching tests have been run,
+ // ensure that they are cleaned up
+ if (gFileCacheRun)
+ {
+ TUint i = 0;
+ // First close all the open handles to the RFile objects open
+ for (i = 0; i < KNumFilesOrig; i++)
+ {
+ gFile[i].Close();
+ }
+
+ // Now call EmptyRamZone on every zone to ensure that
+ // discardable pages are cleaned up
+
+ GetAllPageInfo();
+ for (i = 0; i < gZoneCount; i++)
+ {
+ TUint zoneID = gZoneConfigArray[i].iZoneId;
+ Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, zoneID);
+ }
+ gFileCacheRun = EFalse;
+ }
+ }
+
+//
+// TestCleanup
+//
+// Cleans up all the allocations made at the beginning of the test
+//
+void TestCleanup()
+ {
+
+ Ldd.ResetDriver();
+
+ // Revert the cleared flags to their original values before the tests were carried out
+ RestoreRamZoneFlags();
+
+ // Reset the DP cache and remove any allocated chunks and fixed pages.
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ ResetDPCache();
+ Ldd.FreeAllFixedPages();
+ Ldd.FreeFromAllZones();
+ FSCachCleanUp();
+
+ User::Free(gPrefArray);
+ gPrefArray = NULL;
+
+ User::Free(gOrigFlagArray);
+ gOrigFlagArray = NULL;
+
+ User::Free(gCandList1);
+ gCandList1 = NULL;
+
+ User::Free(gCandList2);
+ gCandList2 = NULL;
+
+ User::Free(gOriginalPageCountArray);
+ gOriginalPageCountArray = NULL;
+
+ // Output the last possible state of memory
+ if (!gFailPrintPageInfo)
+ PrintPageInfo();
+
+ User::Free(gZoneConfigArray);
+ gZoneConfigArray = NULL;
+
+ User::Free(gZoneUtilArray);
+ gZoneUtilArray = NULL;
+
+ }
+
+
+// TestSetup
+//
+// Get the necessary information needed to carry out the tests
+//
+TInt TestSetup()
+ {
+ // Get the MMC drive
+ gDrive = GetDrive();
+
+ // first get the number of zones
+ TInt ret = UserSvr::HalFunction(EHalGroupRam,ERamHalGetZoneCount,&gZoneCount,0);
+ if (ret != KErrNone)
+ {
+ test.Printf(_L("Cannot obtain the number of zones\n"));
+ return ret;
+ }
+ test.Printf(_L("RAM Zones (count=%u)\n"),gZoneCount);
+
+ // Obtain the size of the RAM and the size of a page
+ ret = HAL::Get(HAL::EMemoryRAM, gRamSize);
+ if (ret != KErrNone)
+ {
+ test.Printf(_L("Cannot obtain the size of RAM\n"));
+ return ret;
+ }
+
+ // Retrieve the page size and use it to detemine the page shift (assumes 32-bit system).
+ ret = HAL::Get(HAL::EMemoryPageSize, gPageSize);
+ if (ret != KErrNone)
+ {
+ test.Printf(_L("Cannot obtain the page size\n"));
+ return ret;
+ }
+
+ TUint32 pageMask = gPageSize;
+ TUint i = 0;
+ for (; i < 32; i++)
+ {
+ if (pageMask & 1)
+ {
+ if (pageMask & ~1u)
+ {
+ test.Printf(_L("ERROR - page size not a power of 2"));
+ return KErrNotSupported;
+ }
+ gPageShift = i;
+ break;
+ }
+ pageMask >>= 1;
+ }
+
+ gZoneConfigArray = (SRamZoneConfig *)User::AllocZ(sizeof(SRamZoneConfig) * gZoneCount);
+ if (gZoneConfigArray == NULL)
+ return KErrNoMemory;
+ gZoneUtilArray = (SRamZoneUtilisation *)User::AllocZ(sizeof(SRamZoneUtilisation) * gZoneCount);
+ if (gZoneUtilArray == NULL)
+ return KErrNoMemory;
+ gPrefArray = (TInt *)User::AllocZ(sizeof(TInt) * gZoneCount);
+ if (gPrefArray == NULL)
+ return KErrNoMemory;
+ gOrigFlagArray = (TUint8 *)User::AllocZ(sizeof(TUint8) * gZoneCount);
+ if (gOrigFlagArray == NULL)
+ return KErrNoMemory;
+ gOriginalPageCountArray = (SRamZoneUtilisation *)User::AllocZ(sizeof(SRamZoneUtilisation) * gZoneCount);
+ if (gOriginalPageCountArray == NULL)
+ return KErrNoMemory;
+
+ gCandList1 = (TInt *)User::AllocZ(sizeof(TInt) * gZoneCount);
+ if (gCandList1 == NULL)
+ return KErrNoMemory;
+ gCandList2 = (TInt *)User::AllocZ(sizeof(TInt) * gZoneCount);
+ if (gCandList2 == NULL)
+ return KErrNoMemory;
+
+ GetAllPageInfo();
+ PrintPageInfo();
+
+ // Store the original flags
+ for (i=0; i < gZoneCount; i++)
+ gOrigFlagArray[i] = gZoneConfigArray[i].iFlags;
+
+ // Now clear the flags for carrying out tests
+ Ldd.ResetDriver();
+ ResetRamZoneFlags();
+
+
+ // Check whether the ROM is paged or not
+ TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
+ if(!romHeader->iPageableRomStart)
+ {
+ test.Printf(_L("Not a Paged ROM - Skipping all discardable page tests.\n"));
+ gPagedRom = EFalse;
+ }
+ else
+ {// Save the current state of the DP cache so it can be restored when required and
+ // after the test has finished.
+ TUint currentCacheSize;
+ DPTest::CacheSize(gOriginalMinCacheSize, gOriginalMaxCacheSize, currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ gOriginalMinCacheSize >> gPageShift, gOriginalMaxCacheSize >> gPageShift,
+ currentCacheSize >> gPageShift));
+ }
+
+ return KErrNone;
+ }
+
+
+//
+// UpdateRamInfo
+//
+// Updating the various RAM information
+//
+void UpdateRamInfo()
+ {
+ HAL::Get(HAL::EMemoryRAMFree, gFreeRam);
+ TESTDEBUG(gRamUsed = gRamSize - gFreeRam);
+ }
+
+
+//
+// CheckRamDifference
+//
+// Checks the difference between the initial free RAM and the end free RAM
+//
+void CheckRamDifference()
+ {
+ if (gInitialRam == gEndRam)
+ {
+ TESTDEBUG(test.Printf(_L("No RAM was lost during this test\n")));
+ }
+ else
+ {
+ TInt diff = gInitialRam - gEndRam;
+
+
+ gTotalRamLost = gTotalRamLost + diff;
+ }
+ }
+
+TInt VerifyMovDisAlloc();
+//
+// TestStart
+//
+// Updates the RAM information at the beginning of a test step
+//
+void TestStart()
+ {
+ test(!gTestStarted);
+ gTestStarted = ETrue;
+
+ Ldd.ResetDriver();
+
+ Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ if (VerifyMovDisAlloc() != KErrNone)
+ {
+ CLEANUP(;);
+ TEST_FAIL;
+ }
+
+ UpdateRamInfo();
+ gInitialRam = gFreeRam;
+ TESTDEBUG(test.Printf(_L("Initial Free RAM = 0x%x, Initial RAM Used = 0x%x\n"), gFreeRam, gRamUsed));
+ }
+
+
+void RemoveChunkAlloc(RChunk*& aChunkArray, TUint& aChunkArraySize);
+//
+// TestEnd
+//
+// Updates RAM information at end of test step and checks the RAM delta
+//
+void TestEnd()
+ {
+ test(gTestStarted);
+ gTestStarted = EFalse;
+
+ gDefragMaxPages = 0;
+
+ // Clean up anything that may need to be cleaned.
+ ResetRamZoneFlags();
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ ResetDPCache();
+ Ldd.FreeAllFixedPages();
+ FSCachCleanUp();
+
+ UpdateRamInfo();
+ gEndRam = gFreeRam;
+ TESTDEBUG(test.Printf(_L("End RAM Free = 0x%x, End RAM Used = 0x%x\n"), gEndRam, gRamUsed));
+ CheckRamDifference();
+ test.Printf(_L(" \n"));
+ }
+
+//
+// CheckZonesSwitchedOff
+//
+// Checks that zones have been switched off
+//
+TBool CheckZonesSwitchedOff()
+ {
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gOriginalPageCountArray[i].iFreePages != gOriginalPageCountArray[i].iPhysPages &&
+ gZoneUtilArray[i].iFreePages == gZoneUtilArray[i].iPhysPages)
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+//
+// CheckZoneIsOff
+//
+// Checks if a particular zone is empty
+//
+TBool CheckZoneIsOff(TUint aZoneIndex)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[aZoneIndex].iFreePages == gZoneUtilArray[aZoneIndex].iPhysPages)
+ {
+ TESTDEBUG(test.Printf(_L("Zone index %d is Empty\n"), aZoneIndex));
+ return ETrue;
+ }
+ else
+ {
+ TESTDEBUG(test.Printf(_L("Zone index %d is Not empty\n"), aZoneIndex));
+ return EFalse;
+ }
+ }
+
+
+//
+// GetPrefOrder
+//
+// Go through each zone ordering them in preference order
+//
+void GetPrefOrder()
+ {
+ GetAllPageInfo();
+ TESTDEBUG(PrintPageInfo());
+
+ for (TUint i=0; i < (TUint)gZoneCount; i++)
+ gPrefArray[i] = KErrNotFound;
+
+ for (TUint curIndex = 0; curIndex < gZoneCount; curIndex++)
+ {
+ TBool currentEmpty = gZoneUtilArray[curIndex].iPhysPages == gZoneUtilArray[curIndex].iFreePages;
+ TUint currentPref = gZoneConfigArray[curIndex].iPref;
+ TUint currentImmovPages = gZoneUtilArray[curIndex].iAllocFixed +
+ gZoneUtilArray[curIndex].iAllocUnknown;
+ TUint morePrefCnt = 0;
+ for (TUint index = 0; index < gZoneCount; index++)
+ {// A RAM zone with the same iPref is more preferable if it has
+ // more immovable pages.
+ if (gZoneConfigArray[index].iPref < currentPref ||
+ (gZoneConfigArray[index].iPref == currentPref &&
+ (currentImmovPages < gZoneUtilArray[index].iAllocFixed + gZoneUtilArray[index].iAllocUnknown ||
+ (currentEmpty &&
+ gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages))))
+ {
+ morePrefCnt++;
+ }
+ }
+
+ while (gPrefArray[morePrefCnt] != KErrNotFound)
+ {// Zone(s) of this preference and size already exist so
+ // place this one after it/them
+ morePrefCnt++;
+ }
+ gPrefArray[morePrefCnt] = curIndex;
+ }
+ }
+
+//
+// ZonesSamePref
+//
+// Return ETrue if the RAM zones are of the same preference.
+//
+// NOTE - This requires GetAllPageInfo() to have already been called.
+//
+TBool ZonesSamePref(TUint aZoneIndex1, TUint aZoneIndex2)
+ {
+ TBool zoneEmpty1 = gZoneUtilArray[aZoneIndex1].iFreePages == gZoneUtilArray[aZoneIndex1].iPhysPages;
+ TBool zoneEmpty2 = gZoneUtilArray[aZoneIndex2].iFreePages == gZoneUtilArray[aZoneIndex2].iPhysPages;
+ if (gZoneConfigArray[aZoneIndex1].iPref == gZoneConfigArray[aZoneIndex2].iPref &&
+ (gZoneUtilArray[aZoneIndex1].iAllocFixed + gZoneUtilArray[aZoneIndex1].iAllocUnknown ==
+ gZoneUtilArray[aZoneIndex2].iAllocFixed + gZoneUtilArray[aZoneIndex2].iAllocUnknown &&
+ (zoneEmpty1 == zoneEmpty2)))
+ {
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+//
+// FindMostPrefEmpty
+//
+// Checks all zones and returns the most preferable RAM zone which
+// is completely emtpy
+//
+// @param aZoneIndex On return this will contain the index into gZoneUtilArray of the most preferable empty RAM zone.
+// @param aPrefIndex On return this will contain the index into gPrefArray of the most preferable empty RAM zone.
+//
+// @return KErrNotFound if a zone cannot be found, else KErrNone
+//
+TInt FindMostPrefEmpty(TUint& aZoneIndex, TUint* aPrefIndex = NULL)
+ {
+ // Get the most pref zone which is completely free to use as a test zone
+ GetPrefOrder();
+ TUint prefIndex = 0;
+ for (; prefIndex < gZoneCount; prefIndex++)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[zoneIndex].iFreePages == gZoneUtilArray[zoneIndex].iPhysPages)
+ {
+ aZoneIndex = zoneIndex;
+ if (aPrefIndex)
+ {
+ *aPrefIndex = prefIndex;
+ }
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+//
+// FindLeastPrefEmpty
+//
+// Checks all zones and returns the least preferable RAM zone which
+// is completely emtpy
+//
+// @param aZoneIndex On return this will contain the index into gZoneUtilArray of the least preferable empty RAM zone.
+// @param aPrefIndex On return this will contain the index into gPrefArray of the least preferable empty RAM zone.
+//
+// @return KErrNotFound if a zone cannot be found, else KErrNone
+//
+TInt FindLeastPrefEmpty(TUint& aZoneIndex, TUint* aPrefIndex = NULL)
+ {
+ // Get the most pref zone which is completely free to use as a test zone
+ GetPrefOrder();
+ TInt prefIndex = gZoneCount - 1;
+ for (; prefIndex >= 0; prefIndex--)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[zoneIndex].iFreePages == gZoneUtilArray[zoneIndex].iPhysPages)
+ {
+ aZoneIndex = zoneIndex;
+ if (aPrefIndex)
+ {
+ *aPrefIndex = (TUint)prefIndex;
+ }
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+
+//
+// FindMostPrefWithFree
+//
+// Checks all zones and returns the most preferable RAM zone which
+// has at least 1 free page
+//
+// @param aZoneIndex On return this will contain the index into gZoneUtilArray of the most preferable RAM zone with free pages.
+// @param aPrefIndex On return this will contain the index into gPrefArray of the most preferable RAM zone with free pages.
+//
+// @return KErrNotFound if a zone cannot be found, else KErrNone
+//
+TInt FindMostPrefWithFree(TUint& aZoneIndex, TUint* aPrefIndex = NULL)
+ {
+ // Get the most pref zone which has free pages
+ GetPrefOrder();
+ TUint prefIndex = 0;
+ for (; prefIndex < gZoneCount; prefIndex++)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[zoneIndex].iFreePages)
+ {
+ aZoneIndex = zoneIndex;
+ if (aPrefIndex)
+ {
+ *aPrefIndex = prefIndex;
+ }
+ return KErrNone;
+ }
+ }
+ return KErrNotFound;
+ }
+//
+// CanGenSucceed
+//
+// Check whether a call to TRamDefragRequest::DefragRam() would be able to
+// succeed or not.
+//
+TBool CanGenSucceed()
+ {
+ GetPrefOrder();
+ TBool genSucceed = EFalse;
+ // Work out if general has anything to do
+ for(TInt prefIndex = (TInt)gZoneCount-1; prefIndex >= 0; prefIndex--)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ TESTDEBUG(test.Printf(_L("prefIndex = %d zoneIndex = 0x%x\n"), prefIndex, zoneIndex));
+
+ TUint samePrefCount = 1;
+ TUint samePrefSucceed = 0;
+ // The number of zones of this preference that will be skipped by the general defrag
+ TUint samePrefEmptyImmovable = 0;
+
+ // Determine how many zones have the same preference as this one
+ TInt prevPrefIndex = (prefIndex != 0)? (prefIndex - 1) : -1;
+ for (; prevPrefIndex >= 0; prevPrefIndex--)
+ {
+ TUint prevIndex = gPrefArray[prevPrefIndex];
+ if (ZonesSamePref(zoneIndex, prevIndex))
+ {
+ samePrefCount++;
+ }
+ else // no more zones with this preference
+ break;
+ }
+ TESTDEBUG(test.Printf(_L("samePrefCount = %d\n"), samePrefCount));
+
+ for (TInt l = prefIndex - (samePrefCount-1); l <= prefIndex; l++)
+ {
+ TUint curPrefIndex = gPrefArray[l];
+ TESTDEBUG(test.Printf(_L("curPrefIndex = %d\n"), curPrefIndex));
+ if (gZoneUtilArray[curPrefIndex].iFreePages != gZoneConfigArray[curPrefIndex].iPhysPages)
+ {
+ TBool clearMovable = EFalse;
+ TBool clearDiscardable = EFalse;
+
+ if (gZoneUtilArray[curPrefIndex].iAllocUnknown || gZoneUtilArray[curPrefIndex].iAllocFixed)
+ {
+ TESTDEBUG(test.Printf(_L("unknown or fixed\n")));
+ samePrefEmptyImmovable++;
+ continue;
+ }
+ if (gZoneUtilArray[curPrefIndex].iAllocMovable)
+ {// determine if movable can potentially be cleared from this zone
+ TUint freeInLower = 0;
+ for (TInt j=0; j <= prefIndex; j++)
+ {
+ TUint idx = gPrefArray[j];
+ if (idx == curPrefIndex)
+ continue;
+ freeInLower += gZoneUtilArray[idx].iFreePages;
+ }
+ if (gZoneUtilArray[curPrefIndex].iAllocMovable <= freeInLower)
+ {
+ clearMovable = ETrue;
+ TESTDEBUG(test.Printf(_L("Can clear movable, curPrefIndex = %d\n"), curPrefIndex));
+ }
+ }
+ else
+ {
+ TESTDEBUG(test.Printf(_L("Can clear movable, curPrefIndex = %d\n"), curPrefIndex));
+ clearMovable = ETrue;
+ }
+ if (gZoneUtilArray[curPrefIndex].iAllocDiscardable)
+ {
+ if (gPagedRom)
+ {
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TUint spareCache = currentCacheSize - minCacheSize;
+ if (spareCache >= gZoneUtilArray[curPrefIndex].iAllocDiscardable )
+ {
+ clearDiscardable = ETrue;
+ TESTDEBUG(test.Printf(_L("Paged: Can clear discardable\n")));
+ }
+ else
+ {// determine space for discardable in more preferable zones
+ TUint freeInLower = 0;
+ for (TInt j=0; j <= prefIndex; j++)
+ {
+ TUint idx = gPrefArray[j];
+ if (idx == curPrefIndex)
+ continue;
+ freeInLower += gZoneUtilArray[idx].iFreePages;
+ }
+ if (gZoneUtilArray[curPrefIndex].iAllocDiscardable - spareCache <= freeInLower)
+ {
+ clearDiscardable = ETrue;
+ TESTDEBUG(test.Printf(_L("Paged: Can clear discardable curPrefIndex = %d\n"), curPrefIndex));
+ }
+ }
+ }
+ else
+ {//Should always be OK to discard as no min cache size on non-paged ROMS
+ clearDiscardable = ETrue;
+ test.Printf(_L("Can clear discardable curPrefIndex = %d\n"), curPrefIndex);
+ }
+ }
+ else
+ {
+ clearDiscardable = ETrue;
+ }
+
+ if (clearDiscardable && clearMovable)
+ {
+ samePrefSucceed++;
+ TESTDEBUG(test.Printf(_L("General should succeed ID=%x\n"), gZoneConfigArray[curPrefIndex].iZoneId));
+ }
+ }
+ else
+ {//zone already empty
+ samePrefEmptyImmovable++;
+ }
+ }
+ if (samePrefSucceed == 0 && samePrefEmptyImmovable == 0)
+ {// no zones can be defragged and none are already empty/have immovable.
+ break;
+ }
+ if (samePrefEmptyImmovable != samePrefCount)
+ {// Have reached some zones with allocated pages in them.
+ if (samePrefSucceed + samePrefEmptyImmovable == samePrefCount)
+ {// general should definitely succeed as each of the zones of this preference
+ // can be emptied or are already empty/have immovable pages allocated.
+ TESTDEBUG(test.Printf(_L("General should succeed \n")));
+ genSucceed = ETrue;
+ }
+ break;
+ }
+ prefIndex -= samePrefCount - 1;
+ }
+ return genSucceed;
+ }
+
+
+//
+// ReadByte
+//
+// Read a particular byte
+//
+TUint8 ReadByte(volatile TUint8* aPtr)
+ {
+ return *aPtr;
+ }
+
+
+//
+// AllocDiscardable
+//
+// Allocate Discardable pages in the form of demand paged pages
+//
+// @param aNumDiscardableBytes On return this will contain the number of discardable bytes above the min cache size.
+// @param aMaxBytes The new limit for maximum number of bytes in the DP cache, set to KMaxTUInt64 to fill RAM.
+// @param aMinOffsetBytes When not set to KMaxTUint64, this sets the min cache size to be the max cache size - aMinOffsetBytes.
+//
+TInt AllocDiscardable(TInt& aNumDiscardableBytes, TUint64 aMaxBytes = KMaxTUint64, TUint64 aMinOffsetBytes = KMaxTUint64)
+ {
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+
+ TESTDEBUG(test.Printf(_L("SetCacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x\n"), minCacheSize >> gPageShift, aMaxBytes >> gPageShift));
+
+ if (aMaxBytes == KMaxTUint64)
+ {// Need to fill all of free memory with discardable pages
+ UpdateRamInfo();
+ maxCacheSize = minCacheSize + gFreeRam;
+ if (aMinOffsetBytes != KMaxTUint64)
+ {// Set the min cache size relative to the max cache size.
+ minCacheSize = maxCacheSize - aMinOffsetBytes;
+ }
+ TESTDEBUG(test.Printf(_L("free 0x%x max 0x%x min 0x%x\n"), gFreeRam, maxCacheSize, minCacheSize));
+ }
+ else
+ {
+ maxCacheSize = aMaxBytes;
+ }
+
+ TInt r = DPTest::SetCacheSize(maxCacheSize, maxCacheSize);
+ if (r != KErrNone)
+ return r;
+ r = DPTest::SetCacheSize(minCacheSize, maxCacheSize);
+ if (r != KErrNone)
+ return r;
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("After CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+
+ aNumDiscardableBytes = currentCacheSize - minCacheSize;
+ TESTDEBUG(test.Printf(_L("Number of discardable bytes 0x%x\n"), aNumDiscardableBytes));
+
+ if (aMaxBytes == KMaxTUint64)
+ {
+ UpdateRamInfo();
+ if (gFreeRam != aNumDiscardableBytes)
+ {// The only free RAM should be that of the DP cache.
+ test.Printf(_L("gFreeRam 0x%x aNumDiscardableBytes 0x%x\n"), gFreeRam, aNumDiscardableBytes);
+ return KErrGeneral;
+ }
+ }
+ return KErrNone;
+ }
+
+
+//
+// ResetDPCache
+//
+// Flush the cache and set the boundaries back to their original values
+//
+void ResetDPCache()
+ {
+ if (gPagedRom)
+ {
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ TESTDEBUG(test.Printf(_L("FlushCache\n")));
+ TInt r = DPTest::FlushCache();
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("After CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+
+
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMaxCacheSize);
+ TESTDEBUG(test.Printf(_L("SetCacheSize returns r = %d\n"), r));
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("After CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ }
+ }
+
+//
+// WriteToChunk
+//
+// Write to a number of chunks
+//
+TInt WriteToChunk(RChunk* aChunkArray, TUint aChunkArraySize, TInt aChunk, TUint8 aStart=0)
+ {
+ for (TUint i=0; i<10; i++) // Write to all chunks 10 times
+ {
+ for (TUint j=0; j < aChunkArraySize; j++) //Write to all open chunks except aChunk.
+ {
+ if (aChunkArray[j].Handle() != NULL)
+ {
+ if ((TInt)j == aChunk) // Don't write to specified chunk
+ {
+ continue;
+ }
+ TUint8* base = aChunkArray[j].Base();
+ for (TUint8 k = aStart; k < aStart + 10; k++)
+ {
+ *base++ = k; // write 0 - 9 to the chunk
+ }
+ }
+ }
+ }
+ return KErrNone;
+ }
+
+
+//
+// ReadChunk
+//
+// Read chunks - If a chunk is specified, that particular chunk is not read
+//
+TInt ReadChunk(RChunk* aChunkArray, TUint aChunkArraySize, TInt aChunk=-1)
+ {
+ for (TUint j=0; j < aChunkArraySize; j++) //Read all open chunks
+ {
+ if (aChunkArray[j].Handle() != NULL)
+ {
+ if ((TInt)j == aChunk) // Don't read specified chunk
+ {
+ continue;
+ }
+ TUint8* base = aChunkArray[j].Base();
+ while ((aChunkArray[j].Base() + aChunkArray[j].Size()) != base)
+ {
+ READ(base++);
+ }
+ }
+ }
+ return KErrNone;
+ }
+
+
+//
+// RemoveChunkAlloc
+//
+// Remove ALL chunks allocated
+//
+// @param aChunkArray The array that stores a reference to the chunks created.
+// @param aChunkArraySize The size of aChunkArray.
+//
+void RemoveChunkAlloc(RChunk*& aChunkArray, TUint& aChunkArraySize)
+ {
+ TInt closedChunks = 0;
+
+ if (aChunkArray == NULL)
+ {// The chunk array has already been deleted.
+ return;
+ }
+
+ for (TUint i = 0; i < aChunkArraySize; i++)
+ {
+ if (aChunkArray[i].Handle() != NULL)
+ {
+ aChunkArray[i].Close();
+ closedChunks ++;
+ }
+ }
+ delete[] aChunkArray;
+ aChunkArray = NULL;
+ aChunkArraySize = 0;
+ UpdateRamInfo();
+ test.Printf(_L("Free RAM after closing %d chunks = 0x%x\n"),closedChunks,gFreeRam);
+ }
+
+
+TBool SpaceAvailForPageTables(TUint aZoneIndex, TInt aNumPages)
+ {
+ // Every 1MB allocated needs a new page table
+ const TUint KDataBytesPerPageTable = 1024 * 1024;
+
+ // 1 Page can fit 4 page tables
+ const TUint KPageTablesPerPage = 4;
+
+
+ GetAllPageInfo();
+ if (aNumPages == KFillAllMovable)
+ {
+ aNumPages = gTotalPageCount.iFreePages;
+ }
+
+ TUint allocBytes = aNumPages << gPageShift;
+
+ // Add 1 as you always require at least 1 page table
+ TUint pageTablesRequired = (allocBytes / KDataBytesPerPageTable) + 1;
+ // Add 1 as the first 1-3 page tables may require a new page.
+ TUint pageTablePagesRequired = (pageTablesRequired / KPageTablesPerPage) + 1;
+
+ // Determine the number of free pages in the other zones
+ TUint freeInOther = 0;
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (index != aZoneIndex)
+ {
+ freeInOther += gZoneUtilArray[index].iFreePages;
+ }
+ }
+
+ // Need an overhead for the heap to grow (5 pages)
+ const TUint KOverhead = 5;
+ if (freeInOther < pageTablePagesRequired + KOverhead)
+ {// Not enough space in other zones to fit all page tables
+ test.Printf(_L("No space in other zones for page table pages\n"));
+ return EFalse;
+ }
+ // There is space available in the other zones to fit all the page tables
+ return ETrue;
+ }
+//
+// AllocMovable
+//
+// Allocate movable memory in the form of chunks
+//
+// @param aChunkArray The array to store a reference to the chunks created.
+// @param aChunkArraySize The size of aChunkArray.
+// @param aNumChunks The number of chunks to create.
+// @param aNumPages The size of each chunk.
+//
+TInt AllocMovable(RChunk*& aChunkArray, TUint& aChunkArraySize, TInt aNumChunks, TUint aChunkSize=KChunkDefaultSize, TBool aForceFill = ETrue)
+ {
+ TUint i = 0;
+ TInt r = 0;
+ TUint chunksAllocd = 0;
+ TBool fillAll = EFalse;
+
+ TInt numChunks = aNumChunks;
+ UpdateRamInfo();
+ // Allocate chunks to take up all of memory with the maximum number of chunks
+ if (aNumChunks == KFillAllMovable)
+ {
+ fillAll = ETrue;
+ if (aChunkSize == KChunkDefaultSize)
+ {
+ numChunks = KMaxChunks;
+ aChunkSize = gFreeRam / numChunks;
+ }
+ else
+ {
+ numChunks = gFreeRam / aChunkSize;
+ }
+ }
+
+ test.Printf(_L("gFreeRam = 0x%x, aChunkSize = 0x%x, numChunks = %d\n"), gFreeRam, aChunkSize, numChunks);
+
+ // Allocate as many chunks as is specified, either with the default chunk size or a specified chunk size
+ if (aChunkArray == NULL)
+ {
+ aChunkArraySize = numChunks;
+ aChunkArray = new RChunk[aChunkArraySize];
+ if (aChunkArray == NULL)
+ return KErrNoMemory;
+ }
+
+ // Create chunks for each RChunk with a NULL handle.
+ for (i = 0; i < aChunkArraySize; i++)
+ {
+ if (aChunkArray[i].Handle() == NULL)
+ {
+ // Keep going even if a chunk creation fails as the flag tests rely
+ // on this.
+ r = aChunkArray[i].CreateLocal(aChunkSize, aChunkSize);
+ if (r != KErrNone && fillAll && aForceFill)
+ {
+ while (aChunkArray[i].CreateLocal(aChunkSize, aChunkSize) != KErrNone)
+ {
+ aChunkSize -= gPageSize;
+ }
+ }
+ if (r == KErrNone)
+ {
+ chunksAllocd++;
+ }
+ }
+ User::After(10); // Wait so that the next chunk gets allocated in the next time slice
+ }
+ test.Printf(_L("Number of chunks allocd = %d\n"),chunksAllocd);
+ return r;
+ }
+
+//
+// ZoneAllocMovable
+//
+// Allocate the specified number of movable pages to a specific zone
+// If the number of pages is not specified, then fill the specified zone with
+// movable pages
+//
+// @param aChunkArray The array to store a reference to the chunks created.
+// @param aChunkArraySize The size of aChunkArray.
+// @param aZoneIndex The zone index to allocate movable pages to.
+// @param aNumPages The number of movable pages to allocate.
+//
+TInt ZoneAllocMovable(RChunk*& aChunkArray, TUint& aChunkArraySize, TUint aZoneIndex, TUint aNumPages = KMaxTUint)
+ {
+ ResetRamZoneFlags();
+ TInt r = KErrNone;
+ TUint allocBytes = 0;
+
+ if (aNumPages == KMaxTUint)
+ {
+ aNumPages = gZoneUtilArray[aZoneIndex].iFreePages;
+ }
+
+ allocBytes = aNumPages << gPageShift;
+
+ if (!SpaceAvailForPageTables(aZoneIndex, aNumPages))
+ {
+ return KErrGeneral;
+ }
+
+ // Block all other zones from allocation
+ for(TUint index = 0; index < gZoneCount; index++)
+ {
+ if (index == aZoneIndex)
+ {
+ r = Ldd.SetZoneFlag(gZoneConfigArray[index].iZoneId, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ }
+ else
+ {
+ r = Ldd.SetZoneFlag(gZoneConfigArray[index].iZoneId, gZoneConfigArray[index].iFlags, NO_MOVE_FLAG);
+ }
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set RAM zone flag on zone %d r = %d\n"), index, r);
+ return r;
+ }
+ }
+
+ // Allocate the movable pages
+ r = AllocMovable(aChunkArray, aChunkArraySize, 1, allocBytes);
+
+ ResetRamZoneFlags();
+ return r;
+ }
+
+//
+// ZoneAllocDiscard
+//
+// Allocate the specified number of discardable pages to a specific zone
+//
+// @param aZoneIndex The zone index to allocate discardable pages to.
+// @param aNumPages The number of discardable pages to allocate.
+// @param aDisPages On return this will contain the number of discardable pages allocated
+//
+TInt ZoneAllocDiscard(TUint aZoneIndex, TUint aNumPages, TInt& aDisPages)
+ {
+ TInt r = KErrNone;
+ ResetRamZoneFlags();
+
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ if (index == aZoneIndex)
+ {
+ r = Ldd.SetZoneFlag(zoneID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ }
+ else
+ {
+ r = Ldd.SetZoneFlag(zoneID, gZoneConfigArray[index].iFlags, NO_DISCARD_FLAG);
+ }
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set flag r = %d\n"), r);
+ return r;
+ }
+ }
+
+ TUint disBytes = gTotalPageCount.iDiscardablePages + aNumPages << gPageShift;
+ r = AllocDiscardable(aDisPages, disBytes);
+ aDisPages = aDisPages >> gPageShift;
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Discardable pages not allocated r = %d\n"), r);
+ }
+ ResetRamZoneFlags();
+ return r;
+ }
+
+//
+// FreeMovable
+//
+// Free movable pages by closing chunks.
+// The function will close every other chunk so that the movable pages are scattered in every zone
+//
+// @param aChunkArray The array that stores reference to the chunks created.
+// @param aChunkArraySize The size of aChunkArray.
+//
+TInt FreeMovable(RChunk* aChunkArray, TUint aChunkArraySize)
+ {
+ TUint i;
+ TInt closedChunks = 0;
+
+ for (i=0; i < aChunkArraySize; i+=2) // Close every other chunk
+ {
+ if (aChunkArray[i].Handle() != NULL)
+ {
+ aChunkArray[i].Close();
+ closedChunks ++;
+ }
+ }
+ UpdateRamInfo();
+ test.Printf(_L("Free RAM after closing %d chunks = 0x%x\n"),closedChunks,gFreeRam);
+ return KErrNone;
+ }
+
+//
+// GetBestZone
+//
+// Obtains the most preferable zone for allocating a specific type of page
+//
+// @param aPageType The page type that we are interested in
+// @param aBestPrefIndex The index into the preference array for the zone.
+//
+// @return KErrNotFound if a zone cannot be found, else the zone index into gZoneUtilArray
+//
+TInt GetBestZone(TInt aPageType, TUint* aBestPrefIndex = NULL)
+ {
+ GetPrefOrder();
+
+
+ switch (aPageType)
+ {
+ case BEST_MOVABLE:
+ case BEST_DISCARDABLE:
+ {
+ TInt bestIndex = KErrNotFound;
+ TUint bestPrefIndex = 0;
+ TUint curIndex = 0;
+ TInt startIndex = KErrNotFound;
+ TBool zoneFound = EFalse;
+ // Find the least preferable zone that has movable or discardable pages
+ for (TInt prefIndex = gZoneCount - 1; prefIndex >= 0; prefIndex--)
+ {
+ curIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[curIndex].iAllocMovable || gZoneUtilArray[curIndex].iAllocDiscardable)
+ {
+ startIndex = prefIndex;
+ break;
+ }
+ }
+ if (startIndex == KErrNotFound)
+ return startIndex;
+
+ // Work up the preference list to look for the best zone
+ for (TInt prefIndex = startIndex; prefIndex >= 0; prefIndex--)
+ {
+ curIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[curIndex].iFreePages)
+ {
+ bestIndex = curIndex;
+ bestPrefIndex = prefIndex;
+ zoneFound = ETrue;
+ break;
+ }
+ }
+
+ // If the zone still isn't found, look down the preference list
+ if (!zoneFound)
+ {
+ for (TUint prefIndex = startIndex; prefIndex < gZoneCount; prefIndex++)
+ {
+ curIndex = gPrefArray[prefIndex];
+ if (gZoneUtilArray[curIndex].iFreePages)
+ {
+ bestIndex = curIndex;
+ bestPrefIndex = prefIndex;
+ zoneFound = ETrue;
+ break;
+ }
+ }
+ }
+
+ test.Printf(_L("leastPref = %d\n"), bestIndex);
+ if (aBestPrefIndex)
+ *aBestPrefIndex = bestPrefIndex;
+ return bestIndex;
+ }
+
+ case BEST_FIXED:
+ for (TUint prefIndex = 0; prefIndex < gZoneCount; prefIndex++)
+ {
+ TUint mostPref = gPrefArray[prefIndex];
+ if (gZoneUtilArray[mostPref].iFreePages != 0 ||
+ gZoneUtilArray[mostPref].iAllocMovable != 0 ||
+ gZoneUtilArray[mostPref].iAllocDiscardable != 0)
+ {
+ test.Printf(_L("mostPref = %d\n"), mostPref);
+ if (aBestPrefIndex)
+ *aBestPrefIndex = prefIndex;
+ return mostPref;
+ }
+ }
+ break;
+ }
+
+ test.Printf(_L("Cannot find zone\n"));
+ return KErrNotFound;
+ }
+
+void GetCandList1(TInt aIndex);
+//
+// VerifyMovDisAlloc
+//
+// Checks that all movable and discardable pages are in the correct RAM zones.
+// Should only be invoked after a general defragmentation or a general
+// defragmentation followed by an allocation.
+//
+// NOTE - This shouldn't be used to verify RAM if a RAM specific allocation or
+// zone claim operation has been performed.
+//
+// @return KErrNone if RAM layout is good, KErrGeneral if not, KErrNotFound if no
+// movable or discardable pages are allocated.
+//
+TInt VerifyMovDisAlloc()
+ {
+ GetPrefOrder();
+ TInt leastInUse = KErrNotFound;
+ TUint requiredMovDis = 0;
+ TUint totalMorePrefInUse = 0;
+ TBool verifySpread = ETrue;
+ TBool prevZoneNotFull = EFalse;
+
+ // Determine which is the least prefable RAM zone in use and how many pages
+ // are allocated of each type.
+ for (TInt prefIndex = gZoneCount - 1; prefIndex >= 0; prefIndex--)
+ {
+ TUint index = gPrefArray[prefIndex];
+ TUint allocMov = gZoneUtilArray[index].iAllocMovable;
+ TUint allocDis = gZoneUtilArray[index].iAllocDiscardable;
+ TUint allocFixed = gZoneUtilArray[index].iAllocFixed;
+ TESTDEBUG(test.Printf(_L("pref ID 0x%x\n"), gZoneConfigArray[index].iZoneId));
+ if (allocMov || allocDis || allocFixed)
+ {
+ TBool zoneNotFull = EFalse;
+ GetCandList1(index);
+ TUint candIndex = 0;
+ for (; candIndex < gZoneCount; candIndex++)
+ {
+ TInt zoneIndexCand = gCandList1[candIndex];
+ if (zoneIndexCand == KInvalidCandIndex)
+ {
+ break;
+ }
+ allocMov += gZoneUtilArray[zoneIndexCand].iAllocMovable;
+ allocDis += gZoneUtilArray[zoneIndexCand].iAllocDiscardable;
+ if (gZoneUtilArray[zoneIndexCand].iFreePages)
+ {
+ zoneNotFull = ETrue;
+ }
+ }
+ prefIndex -= candIndex - 1;
+ if (leastInUse == KErrNotFound)
+ {// Have found least preferable RAM zone that is in use.
+ leastInUse = index;
+ if (allocFixed)
+ {// The least preferable RAM zone has fixed pages in it so
+ // RAM may be more spread out than is necessary.
+ verifySpread = EFalse;
+ }
+ }
+ else
+ {
+ if ((allocMov || allocDis) && prevZoneNotFull)
+ {// The previous least preferable RAM zones were not full so shouldn't
+ // be any movable or discardable pages in the RAM zones of this preference.
+ test.Printf(_L("Movable or discardable pages in more preferable RAM zones unnecessarily\n"));
+ return KErrGeneral;
+ }
+ prevZoneNotFull = zoneNotFull;
+
+ // Not the least preferable RAM zone so add to total allocatable.
+ totalMorePrefInUse += allocMov + allocDis + gZoneUtilArray[index].iFreePages;
+ }
+ requiredMovDis += allocMov + allocDis;
+ }
+ }
+
+ if (leastInUse == KErrNotFound)
+ {// No movable or discardable pages are allocated.
+ test.Printf(_L("No in use RAM zones found????\n"));
+ return KErrNotFound;
+ }
+
+ if (totalMorePrefInUse > requiredMovDis)
+ {// There enough allocatable pages in the RAM zones below the currently
+ // least preferable RAM in use.
+ test.Printf(_L("Memory is spread out totalMorePref 0x%x required 0x%x\n"), totalMorePrefInUse, requiredMovDis);
+ if (verifySpread)
+ return KErrGeneral;
+ }
+ return KErrNone;
+ }
+
+
+//
+// GetCandList1
+//
+// Populates a list of all zones that have the same preference and the same amount
+// of immovable pages
+//
+void GetCandList1(TInt aIndex)
+ {
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ gCandList1[i] = KInvalidCandIndex;
+ }
+
+ TInt candListIndex = 0;
+ GetAllPageInfo();
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ if (ZonesSamePref(aIndex, i))
+ {
+ gCandList1[candListIndex] = i;
+ candListIndex ++;
+ }
+ }
+ }
+
+//
+// GetCandList2
+//
+// Populates a list of all zones that have the same preference and the same amount
+// of immovable pages
+//
+void GetCandList2(TInt aIndex)
+ {
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ gCandList2[i] = KInvalidCandIndex;
+ }
+
+ TInt candListIndex = 0;
+ GetAllPageInfo();
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ if (ZonesSamePref(aIndex, i))
+ {
+ gCandList2[candListIndex] = i;
+ candListIndex ++;
+ }
+ }
+ }
+
+//
+// GetCandListFixed1
+//
+// Populates a list of all zones that have the same preference and the same
+// amount of immovable pages, it will ignore RAM zones that are full of
+// immovable pages as these are the only RAM zones that fixed pages can't be
+// allocated into.
+//
+void GetCandListFixed1(TInt aIndex)
+ {
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ gCandList1[i] = KInvalidCandIndex;
+ }
+
+ TInt candListIndex = 0;
+ GetAllPageInfo();
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ if (ZonesSamePref(aIndex, i) &&
+ gZoneUtilArray[i].iAllocFixed + gZoneUtilArray[i].iAllocUnknown !=
+ gZoneConfigArray[i].iPhysPages)
+ {
+ gCandList1[candListIndex] = i;
+ candListIndex ++;
+ }
+ }
+ }
+
+//
+// MultiGenDefragThreadFunc
+//
+// Called when a general defrag is called to run at the same time as another operation
+//
+TInt MultiGenDefragThreadFunc(TAny* /*aPtr*/)
+ {
+ RRamDefragFuncTestLdd Ldd2;
+ TInt r = Ldd2.Open();
+ if (r != KErrNone)
+ {
+ RDebug::Printf("Unable to open Ldd2 in MultiGenDefragThreadFunc, r = %d\n", r);
+ return r;
+ }
+
+ RThread thisThread = RThread();
+ thisThread.SetPriority(EPriorityLess);
+ r = Ldd2.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ Ldd2.Close();
+ thisThread.Close();
+ return r;
+ }
+
+TBool gTestLoop = EFalse;
+//
+// MultiLoopGenDefragThreadFunc
+//
+// Called when a general defrag is called to run at the same time as another operation
+//
+TInt MultiLoopGenDefragThreadFunc(TAny* /*aPtr*/)
+ {
+ RRamDefragFuncTestLdd Ldd2;
+ TInt r = Ldd2.Open();
+ if (r != KErrNone)
+ {
+ RDebug::Printf("Unable to open Ldd2 in MultiLoopGenDefragThreadFunc, r = %d\n", r);
+ return r;
+ }
+
+ RThread thisThread = RThread();
+ thisThread.SetPriority(EPriorityLess);
+ while (gTestLoop)
+ {
+ r = Ldd2.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ if (r != KErrNone)
+ goto threadExit;
+ }
+threadExit:
+ Ldd2.Close();
+ thisThread.Close();
+ return r;
+ }
+
+//
+// MultiEmptyZoneThreadFunc
+//
+// Called when a zone defrag is called to run at the same time as another operation
+//
+TInt MultiEmptyZoneThreadFunc(TAny* zoneID)
+ {
+ RRamDefragFuncTestLdd Ldd2;
+ TInt r = Ldd2.Open();
+ if (r != KErrNone)
+ {
+ RDebug::Printf("Unable to open Ldd2 in MultiEmptyZoneThreadFunc, r = %d\n", r);
+ return r;
+ }
+
+ RThread thisThread = RThread();
+ thisThread.SetPriority(EPriorityLess);
+ r = Ldd2.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, (TUint)zoneID);
+ Ldd2.Close();
+ thisThread.Close();
+ return r;
+ }
+
+
+//
+// MultiClaimZoneThreadFunc
+//
+// Called when a ClaimRamZone is called to run at the same time as another operation
+//
+TInt MultiClaimZoneThreadFunc(TAny* zoneID)
+ {
+ RRamDefragFuncTestLdd Ldd2;
+ TInt r = Ldd2.Open();
+ if (r != KErrNone)
+ {
+ RDebug::Printf("Unable to open Ldd2 in MultiClaimZoneThreadFunc, r = %d\n", r);
+ return r;
+ }
+
+ RThread thisThread = RThread();
+ thisThread.SetPriority(EPriorityLess);
+ r = Ldd2.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, (TUint)zoneID);
+ Ldd2.Close();
+ thisThread.Close();
+ return r;
+ }
+
+
+//
+// TestAllocStrategies
+//
+// Verifying that pages are allocated correctly. All tests rely on a general defragmentation occuring
+// in TestStart() so that memory is in a defragmented state before the allocations.
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0525
+//! @SYMTestCaseDesc Verifying that pages are allocated correctly
+//! @SYMTestType CIT
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Allocate one chunk to memory.
+//! Check which zone the chunk has been allocated to by checking the
+//! number of movable pages before and after the allocation has taken place.
+//! 2. Allocate one chunk to memory that is large enough to cause an empty RAM
+//! zone to be used.
+//! 3. Allocate a certain number of fixed pages to memory.
+//! Check which zone the chunk has been allocated to by checking the
+//! number of fixed pages before and after the allocation has taken place.
+//! 4. Allocate fixed pages when it is known that discardable pages will need
+//! to be discarded for the allocation to succeed.
+//! 5. Allocate fixed pages when it is known that movable pages will need
+//! to be moved for the allocation to succeed.
+//! 6. Allocate fixed pages when it is known that movable pages will need
+//! to be moved for the allocation to succeed, Determine the "best" zone for fixed pages and allocate 1 more
+//! than that.
+//! 7. Allocate discardable pages by loading pages that are demand paged.
+//! Check which zone the memory has been allocated to by checking the number of
+//! discardable pages before and after the allocation has taken place.
+//!
+//! @SYMTestExpectedResults
+//! 1. The memory has been allocated to the most preferred zone with the least amount of
+//! space accounting for the zone threshold for movable pages.
+//! 2. The new RAM zone is used and the movable page are allocated into it first then the other
+//! more preferable RAM zones.
+//! 3. The fixed pages are allocated to the most preferred zone
+//! 4. The fixed pages are allocatted to the most preferred zone with free, movable or discardable pages in it.
+//! 5. The fixed pages are allocatted to the most preferred zone with free, movable or discardable pages in it.
+//! 6. Extra page is placed in the next preferable to the "best"zone
+//! 7. Memory is allocated to the most preferred zone with the least amount of
+//! space accounting for the zone threshold for discardable pages.
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestAllocStrategies()
+ {
+
+ test.Start(_L("Test1: Check which zone a movable page has been allocated to "));
+ TestStart(); //This will perform a general defrag which should tidy up RAM for us
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ TBool zoneFound = EFalse;
+
+ // Determine if suitable RAM zone exists for testing
+ TInt best = GetBestZone(BEST_MOVABLE);
+ if (best == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ }
+ else
+ {
+ test.Printf(_L("best = %d\n"), best);
+ // Populate the candidate list
+ GetCandList2(best);
+ // Allocate 1 movable page
+ GetOriginalPageCount();
+ if (AllocMovable(gChunkArray1, gChunkArraySize1, 1, gPageSize) != KErrNone)
+ {
+ test.Printf(_L("Not enough free RAM for test - Skipping...\n"));
+ }
+ else
+ {
+ GetAllPageInfo();
+ TInt r = VerifyMovDisAlloc();
+ // Need to check all candidates to see if page has gone into any one of them
+ for (TUint i=0; i < gZoneCount; i++)
+ {
+ if (gCandList2[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ TUint zoneIndex = gCandList2[i];
+ if (gOriginalPageCountArray[zoneIndex].iAllocMovable < gZoneUtilArray[zoneIndex].iAllocMovable)
+ {
+ zoneFound = ETrue;
+ break;
+ }
+ }
+
+ if (r == KErrNone && zoneFound)
+ {
+ test.Printf(_L("Pass: Movable allocated to the zone expected\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: Movable allocated to a zone that was not expected, r %d\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test2: Check that movable pages allocated from least preferable RAM zone to be used\n"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ // Determine if suitable RAM zone exists for testing.
+ TUint bestPrefIndex;
+ best = GetBestZone(BEST_MOVABLE, &bestPrefIndex);
+ TUint morePrefIndex = bestPrefIndex - 1;
+ TUint nextLeastPrefIndex = bestPrefIndex + 1;
+
+
+ // Check number of free pages in the more preferable zones
+ TUint freeInMorePref = 0;
+ for (TUint i = 0; i < bestPrefIndex; i++)
+ {
+ freeInMorePref += gZoneUtilArray[gPrefArray[i]].iFreePages;
+ }
+
+ test.Printf(_L("freeInMorePref = 0x%x\n"), freeInMorePref);
+ const TUint KHeapOverhead = 5; // Room for kernel heap allocations so they don't affect the page count
+ if (best == KErrNotFound || nextLeastPrefIndex >= gZoneCount ||
+ (gZoneUtilArray[gPrefArray[nextLeastPrefIndex]].iFreePages < KHeapOverhead &&
+ freeInMorePref < KHeapOverhead)||
+ gZoneConfigArray[gPrefArray[nextLeastPrefIndex]].iPref == gZoneConfigArray[best].iPref ||
+ gZoneConfigArray[gPrefArray[morePrefIndex]].iPref == gZoneConfigArray[best].iPref)
+ {// No less preferable RAM zone or there are more or less preferable of
+ // same preference so re-ordering potential makes verification too complex.
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ }
+ else
+ {
+ // Ensure the zone is almost full as chunks will get allocated in blocks
+ // by almost filling the best zone with fixed pages, leaving a space (e.g. 20 pages)
+ const TUint KSpaceNeeded = 20;
+ if (gZoneUtilArray[best].iFreePages > KSpaceNeeded)
+ {
+ TUint zoneID = gZoneUtilArray[best].iZoneId;
+ TUint diffAlloc = gZoneUtilArray[best].iFreePages - KSpaceNeeded;
+ TInt r = Ldd.ZoneAllocDiscontiguous(zoneID, diffAlloc);
+ if (r != KErrNone)
+ {
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ }
+
+
+
+ GetAllPageInfo();
+ // Update the number of free pages in the more preferable zones
+ freeInMorePref = 0;
+ for (TUint i = 0; i < bestPrefIndex; i++)
+ {
+ freeInMorePref += gZoneUtilArray[gPrefArray[i]].iFreePages;
+ }
+ TUint origFixed = gTotalPageCount.iFixedPages;
+
+ GetOriginalPageCount();
+
+ // Allocate enough movable pages that the next least preferable RAM zone
+ // will need to be used.
+ TUint movPages = gZoneUtilArray[best].iFreePages + 1;
+ TUint movBytes = movPages << gPageShift;
+ TInt r = AllocMovable(gChunkArray1, gChunkArraySize1, 1, movBytes);
+ if (r != KErrNone)
+ {
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ GetAllPageInfo();
+ TUint curFixed = gTotalPageCount.iFixedPages;
+ TInt difFixed = curFixed - origFixed;
+
+ // If there is space in the more preferable zones then they should be allocated starting from
+ // the "best" zone to the more preferable zones, else from the next least preferable zone to the more preferable zones
+ TUint prefIndex;
+ if ((TInt)freeInMorePref > difFixed)
+ {//No new zones should be turned on, allocation should have gone into bestPrefIndex then down towards most preferred zones
+ TUint nextIndex = gPrefArray[nextLeastPrefIndex];
+ if (gOriginalPageCountArray[best].iAllocMovable >= gZoneUtilArray[best].iAllocMovable ||
+ gOriginalPageCountArray[nextIndex].iAllocMovable < gZoneUtilArray[nextIndex].iAllocMovable)
+ {
+ test.Printf(_L("Movable page allocated incorrectly origFree 0x%x curFree 0x%x nxtPrefFree 0x%x\n"),
+ gOriginalPageCountArray[best].iFreePages, gZoneUtilArray[best].iFreePages,
+ gZoneUtilArray[nextLeastPrefIndex].iFreePages);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ prefIndex = morePrefIndex;
+ }
+ else
+ {// If there are enough free pages in "nextIndex" to fit all movable pages allocated then the movable
+ // page count in "best" should stay the same, else they should be allocated between "nextIndex" and "best".
+ TUint nextIndex = gPrefArray[nextLeastPrefIndex];
+ test.Printf(_L("nextIndex = %d\n"), nextIndex);
+ if (gOriginalPageCountArray[nextIndex].iAllocMovable >= gZoneUtilArray[nextIndex].iAllocMovable ||
+ (gOriginalPageCountArray[nextIndex].iFreePages >= movPages &&
+ gOriginalPageCountArray[best].iAllocMovable != gZoneUtilArray[best].iAllocMovable) ||
+ (gOriginalPageCountArray[nextIndex].iFreePages < movPages &&
+ gOriginalPageCountArray[best].iAllocMovable == gZoneUtilArray[best].iAllocMovable))
+ {
+ test.Printf(_L("Movable page allocated incorrectly origFree 0x%x curFree 0x%x nxtPrefFree 0x%x\n"),
+ gOriginalPageCountArray[nextIndex].iFreePages, gZoneUtilArray[nextIndex].iFreePages,
+ gZoneUtilArray[nextIndex].iFreePages);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ prefIndex = bestPrefIndex;
+ }
+
+ // Check that movable pages have only been allocated into the more
+ // preferable RAM zones if the less preferable ram zones in use are full.
+ prefIndex++;
+ do
+ {
+ prefIndex--;
+ TUint indexCurrent = gPrefArray[prefIndex];
+ TUint indexLessPref = gPrefArray[prefIndex+1];
+
+ if (gOriginalPageCountArray[indexCurrent].iAllocMovable < gZoneUtilArray[indexCurrent].iAllocMovable &&
+ gZoneUtilArray[indexLessPref].iFreePages)
+ {// Current in use zone or less preferable than current has free pages so fail
+ test.Printf(_L("Movable page allocated incorrectly origFree 0x%x curFree 0x%x nxtPrefFree 0x%x\n"),
+ gOriginalPageCountArray[best].iFreePages, gZoneUtilArray[best].iFreePages,
+ gZoneUtilArray[nextLeastPrefIndex].iFreePages);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ }
+ while(prefIndex);
+ test.Printf(_L("Pass: Pages allocated to the zone expected\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test3: Check which zone a fixed page has been allocated to "));
+ for (TUint testStep = 0; testStep < 2; testStep++)
+ {
+ switch (testStep)
+ {
+ case 0:
+ test.Printf(_L("Testing discontiguous allocations\n"));
+ break;
+
+ case 1:
+ test.Printf(_L("Testing contiguous allocations\n"));
+ break;
+ }
+ TestStart();
+ zoneFound = EFalse;
+ GetOriginalPageCount();
+
+ best = GetBestZone(BEST_FIXED);
+ TESTDEBUG(test.Printf(_L("best = %d\n"), best));
+ if (best == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ }
+ else
+ {
+ GetCandList1(best);
+ TInt allocFixedPages = 1; // Try and allocate just 1 fixed page
+ switch (testStep)
+ {
+ case 0:
+ Ldd.AllocateFixed(allocFixedPages);
+ break;
+
+ case 1:
+ TUint allocFixedBytes = allocFixedPages << gPageShift;
+ Ldd.AllocContiguous(allocFixedBytes);
+ break;
+ }
+
+
+ GetAllPageInfo();
+ for (TUint i=0; i<gZoneCount; i++)
+ {
+ if (gCandList1[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ TUint zoneIndex = gCandList1[i];
+ if (gOriginalPageCountArray[zoneIndex].iAllocFixed + allocFixedPages <= gZoneUtilArray[zoneIndex].iAllocFixed)
+ {
+ zoneFound = ETrue;
+ break;
+ }
+ }
+
+ if (zoneFound)
+ {
+ test.Printf(_L("Pass: Chunk has been allocated to the zone expected\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: Fixed been allocated to a zone that was not expected\n"));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+
+ Ldd.FreeAllFixedPages();
+ }
+ TestEnd();
+ }
+
+ test.Next(_L("Test4: Check fixed page allocations will discard pages"));
+ for (TUint testStep = 0; testStep < 2; testStep++)
+ {
+ switch (testStep)
+ {
+ case 0:
+ test.Printf(_L("Testing discontiguous allocations\n"));
+ break;
+
+ case 1:
+ test.Printf(_L("Testing contiguous allocations\n"));
+ break;
+ }
+ TestStart();
+ TInt discardBytes;
+ TInt r;
+
+ if (!gPagedRom)
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ goto SkipTest4;
+ }
+
+ best = GetBestZone(BEST_FIXED);
+ TESTDEBUG(test.Printf(_L("best = %d\n"), best));
+ if (best == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ goto SkipTest4;
+ }
+ // Ensure discardable pages in the preferred RAM zone.
+ r = AllocDiscardable(discardBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ if (discardBytes < gPageSize)
+ {// Can't discard any pages so test can't run.
+ test.Printf(_L("Memory too full to perform test - Skipping...\n"));
+ goto SkipTest4;
+ }
+
+ // Make sure all RAM zones that the fixed page allocation could potentially
+ // go to have discardable pages allocated in it.
+ GetOriginalPageCount();
+ GetCandListFixed1(best);
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gCandList1[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ TUint zoneIndex = gCandList1[i];
+ if (gOriginalPageCountArray[zoneIndex].iAllocDiscardable == 0)
+ {
+ test.Printf(_L("No dicardable pages in one of the candidates RAM zones - Skipping...\n"));
+ goto SkipTest4;
+ }
+ if (gOriginalPageCountArray[zoneIndex].iFreePages != 0)
+ {
+ test.Printf(_L("Some free pages in candidate RAM zone ID%x\n"),
+ gZoneConfigArray[zoneIndex].iZoneId);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+
+ // Allocate 1 fixed page and ensure that it discards a page.
+ switch (testStep)
+ {
+ case 0:
+ r = Ldd.AllocateFixed(1);
+ break;
+
+ case 1:
+ r = Ldd.AllocContiguous(gPageSize);
+ break;
+ }
+
+ // Find RAM zone the fixed page was allocated into.
+ GetAllPageInfo();
+ zoneFound = EFalse;
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gCandList1[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ TUint zoneIndex = gCandList1[i];
+ if (gOriginalPageCountArray[zoneIndex].iAllocFixed < gZoneUtilArray[zoneIndex].iAllocFixed)
+ {
+ zoneFound = ETrue;
+ if (gOriginalPageCountArray[zoneIndex].iAllocDiscardable <= gZoneUtilArray[zoneIndex].iAllocDiscardable &&
+ gOriginalPageCountArray[zoneIndex].iAllocMovable <= gZoneUtilArray[zoneIndex].iAllocMovable)
+ {
+ test.Printf(_L("Fixed pages allocated but no pages discarded in RAM zone ID 0x%x\n"),
+ gZoneConfigArray[zoneIndex].iZoneId);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ }
+
+ if (!zoneFound || r != KErrNone)
+ {
+ test.Printf(_L("No fixed pages were allocated r = %d\n"), r);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Pass: Pages been allocated to the zone expected\n"));
+ }
+ SkipTest4 :
+ // This will free any DP cache pages and fixed pages allocated.
+ TestEnd();
+ }
+
+
+ for (TUint testIndex = 0; testIndex < 2; testIndex++)
+ {
+ switch (testIndex)
+ {
+ case 0:
+ test.Next(_L("Test5: Check fixed page allocations (discontiguous) will move pages"));
+ break;
+
+ case 1:
+ test.Next(_L("Test6: Check fixed page will only go into a new zone if all other fix page zones are full of fix"));
+ break;
+ }
+
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ TInt r = KErrNone;
+ TUint freeInOtherZones = 0;
+ TUint allocatablePages;
+ TUint allocImmovPages;
+ TUint bestPrefIndex;
+ TUint nextBestIndex = 0;
+ const TUint KMovAllocOverhead = 5; // need pages for page tables and kernel heap expansion.
+
+ best = GetBestZone(BEST_FIXED, &bestPrefIndex);
+ TESTDEBUG(test.Printf(_L("best = %d\n"), best));
+ GetCandListFixed1(best);
+ TUint candidates = 0;
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gCandList1[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ candidates++;
+ }
+ if (best == KErrNotFound ||
+ (gZoneUtilArray[best].iAllocMovable == 0 && gZoneUtilArray[best].iFreePages < KMovAllocOverhead) ||
+ candidates != 1)
+ {
+ test.Printf(_L("Cannot find zone or too many equal pref zones to perform test - Skipping...\n"));
+ goto SkipTest5;
+ }
+
+ if (testIndex == 1)
+ {// need to work out what the next best zone would be
+ GetPrefOrder();
+ if (bestPrefIndex + 1 >= gZoneCount)
+ {
+ test.Printf(_L("Cannot find next best zone - Skipping...\n"));
+ goto SkipTest5;
+ }
+ nextBestIndex = gPrefArray[bestPrefIndex + 1];
+ test.Printf(_L("nextBestIndex= %d\n"), nextBestIndex);
+ GetCandListFixed1(nextBestIndex);
+ candidates = 0;
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gCandList1[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ candidates++;
+ }
+ if (gZoneUtilArray[nextBestIndex].iPhysPages == gZoneUtilArray[nextBestIndex].iAllocFixed +
+ gZoneUtilArray[nextBestIndex].iAllocUnknown ||
+ candidates != 1)
+ {
+ test.Printf(_L("Cannot find zone or too many equal pref zones to perform test - Skipping...\n"));
+ goto SkipTest5;
+ }
+ }
+
+
+
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (i != (TUint)best)
+ {
+ freeInOtherZones += gZoneUtilArray[i].iFreePages;
+ }
+ }
+ allocatablePages = gZoneUtilArray[best].iFreePages +
+ gZoneUtilArray[best].iAllocMovable +
+ gZoneUtilArray[best].iAllocDiscardable;
+
+ if (allocatablePages > freeInOtherZones)
+ {
+ test.Printf(_L("Not enough free RAM for test - Skipping...\n"));
+ goto SkipTest5;
+ }
+
+ // Allocate the fixed array before getting any page counts
+ r = Ldd.AllocFixedArray(allocatablePages + 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate fixed array r = %d - Skipping...\n"), r);
+ goto SkipTest5;
+ }
+
+ // Fill the RAM zone with movable pages if none already in it.
+ GetAllPageInfo();
+ if (gZoneUtilArray[best].iAllocMovable == 0)
+ {
+ if (!gZoneUtilArray[best].iFreePages)
+ {
+ test.Printf(_L("RAM zone ID %x too full for test - Skipping...\n"), gZoneConfigArray[best].iZoneId);
+ goto SkipTest5;
+ }
+ // Fill the zone with movable pages
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, best);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to fill zone index %d with movable r = %d\n"), best, r);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+
+ if (GetBestZone(BEST_FIXED) != best)
+ {
+ test.Printf(_L("Unable to complete test; RAM zone reordering - Skipping...\n"));
+ goto SkipTest5;
+ }
+ }
+ // Allocate fixed pages after reseting the allocation flags.
+ GetAllPageInfo();
+ ResetRamZoneFlags();
+ allocatablePages = gZoneUtilArray[best].iFreePages +
+ gZoneUtilArray[best].iAllocMovable +
+ gZoneUtilArray[best].iAllocDiscardable;
+ switch (testIndex)
+ {
+ case 0:
+ r = Ldd.AllocateFixed2(allocatablePages);
+ GetAllPageInfo();
+ allocImmovPages = gZoneUtilArray[best].iAllocFixed + gZoneUtilArray[best].iAllocUnknown;
+ if (r != KErrNone || gZoneConfigArray[best].iPhysPages != allocImmovPages)
+ {
+ test.Printf(_L("RAM zone ID 0x%x not full of immovable pages\n"), gZoneConfigArray[best].iZoneId);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Pass: Pages allocated to the zone expected\n"));
+ }
+ break;
+
+ case 1:
+ GetOriginalPageCount();
+ r = Ldd.AllocateFixed2(allocatablePages + 1);
+ GetAllPageInfo();
+ allocImmovPages = gZoneUtilArray[best].iAllocFixed + gZoneUtilArray[best].iAllocUnknown;
+ if (r != KErrNone || gZoneUtilArray[best].iPhysPages != allocImmovPages ||
+ gZoneUtilArray[nextBestIndex].iAllocFixed <= gOriginalPageCountArray[nextBestIndex].iAllocFixed)
+ {
+ test.Printf(_L("RAM zone ID 0x%x not full of immovable pages or next best ID 0x%x no fix pages\n"),
+ gZoneConfigArray[best].iZoneId, gZoneConfigArray[nextBestIndex].iZoneId);
+ test.Printf(_L("nextBest %d origFix 0x%x curFix 0x%x\n"),
+ nextBestIndex, gOriginalPageCountArray[nextBestIndex].iAllocFixed,
+ gZoneUtilArray[nextBestIndex].iAllocFixed);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+ // Go through every other zone and check that fixed pages haven't increased
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (i != (TUint)best && i != (TUint)nextBestIndex &&
+ gZoneUtilArray[i].iAllocFixed > gOriginalPageCountArray[i].iAllocFixed)
+ {
+ test.Printf(_L("FAIL: Fix page count increased zoneIndex %d orig 0x%x current 0x%x\n"),
+ i, gOriginalPageCountArray[i].iAllocFixed, gZoneUtilArray[i].iAllocFixed);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+ }
+
+ test.Printf(_L("Pass: Pages allocated to the zone expected\n"));
+ break;
+ }
+ SkipTest5 :
+ // This will perform any required clean up.
+ ResetRamZoneFlags();
+ TestEnd();
+ }
+
+ test.Next(_L("Test7: Check which zone a discardable page has been allocated to"));
+ TestStart();
+ if (gPagedRom)
+ {
+ GetAllPageInfo();
+
+ // Try to allocate just one more discardable page
+ TUint allocBytes = (gTotalPageCount.iDiscardablePages + 1) << gPageShift;
+ TInt discardablePages;
+
+ best = GetBestZone(BEST_DISCARDABLE);
+ if (best == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ }
+ else
+ {
+ // Populate the candidate list
+ GetCandList2(best);
+ zoneFound = EFalse;
+ GetOriginalPageCount();
+ TInt r = AllocDiscardable(discardablePages, allocBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r %d\n"), r);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ r = VerifyMovDisAlloc();
+ // Need to check all candidates to see if page has gone into any one of them
+ for (TUint i=0; i < gZoneCount; i++)
+ {
+ if (gCandList2[i] == KInvalidCandIndex)
+ {
+ break;
+ }
+ TUint zoneIndex = gCandList2[i];
+ if (gOriginalPageCountArray[zoneIndex].iAllocDiscardable < gZoneUtilArray[zoneIndex].iAllocDiscardable)
+ {
+ zoneFound = ETrue;
+ break;
+ }
+ }
+
+ if (r == KErrNone && zoneFound)
+ {
+ test.Printf(_L("Pass: Discardable allocated to the zone expected\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: Discardable been allocated to a zone that was not expected r %d\n"), r);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test8: Check fixed page allocations (contiguous) will move pages"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+
+ TInt r = KErrNone;
+ TUint testZoneIndex = 0;
+
+ // Get the most pref zone which is completely free to use as a test zone
+ r = FindMostPrefEmpty(testZoneIndex);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Cannot find empty zone - Skipping...\n"));
+ goto skipTest8;
+ }
+
+
+ // fill the test zone with movable pages
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, testZoneIndex);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[testZoneIndex].iAllocMovable != gZoneUtilArray[testZoneIndex].iPhysPages)
+ {
+ test.Printf(_L("Failed to allocate movable r = %d - Skipping...\n"), r);
+ goto skipTest8;
+ }
+
+ if (gTotalPageCount.iFreePages < 1)
+ {
+ test.Printf(_L("Insufficient memory - totalFreePages = 0x%x - Skipping...\n"), gTotalPageCount.iFreePages);
+ goto skipTest8;
+ }
+
+ for (TUint zoneIndex = 0; zoneIndex < gZoneCount; zoneIndex++)
+ {
+ TUint zoneId = gZoneConfigArray[zoneIndex].iZoneId;
+ if (zoneIndex != testZoneIndex)
+ {
+ r = Ldd.SetZoneFlag(zoneId, gZoneConfigArray[zoneIndex].iFlags, NO_FIXED_FLAG);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set flag on zone index %d r = %d- Skipping...\n"), zoneIndex, r);
+ goto skipTest8;
+ }
+ }
+ }
+
+ //attempt to alloc 1 contiguous fixed page
+ r = Ldd.AllocContiguous(gPageSize);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ !gZoneUtilArray[testZoneIndex].iAllocFixed)
+ {
+ test.Printf(_L("FAIL: no fixed pages in testZoneIndex(%d) r = %d\n"), testZoneIndex, r);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+skipTest8:
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestMovingPages
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0526
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying that pages are moved correctly
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Write to all chunks apart from chunk 9.
+//! Following this start a RAM defrag and whilst defrag is running write to chunk 9.
+//! 2. Fragment the memory. Start a RAM defrag and whilst defrag is running
+//! continuously write different values to the chunks.
+//! 3. Fragment the memory. Following this start a RAM defrag and whilst this
+//! is happening, continuously read from all chunks.
+//! 4. Allocate some movable pages. Call a device driver that will allocate fixed
+//! pages and write values to these fixed pages.
+//! Close every other chunk so that only 5 chunks are now still open.
+//! Following this perform a RAM defrag.
+//! Read from the fixed pages that were originally written to, ensuring
+//! that they have not changed.
+//! 5. Without starting any processes, allocate discardable pages by loading
+//! pages that are demand paged.
+//! Read each of the constants from beginning to end.
+//! Following this perform a RAM defrag.
+//!
+//! @SYMTestExpectedResults
+//! 1. Zones are emptied
+//! 2. Zones are emptied
+//! 3. Zones are emptied
+//! 4. The values written to the fixed pages have not changed.
+//! 5. Zones are emptied
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestMovingPages()
+ {
+ const TInt KAllChunks = -1; // Specifies that all chunks should be written to
+
+ test.Start(_L("Test1: Whilst moving page, change the usage "));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks, KChunkDefaultSize);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ // Find a chunk that exists
+ TInt chunkIndex = gChunkArraySize1 - 1;
+ for (; chunkIndex >= 0 && gChunkArray1[chunkIndex].Handle() == NULL; chunkIndex--);
+ if (chunkIndex < 0)
+ {
+ test.Printf(_L("No chunks were allocated\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ WriteToChunk(gChunkArray1, gChunkArraySize1, chunkIndex);
+
+ TInt r = gTestThread.Create(gTestThreadName,MultiGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+
+ TUint8* base = gChunkArray1[chunkIndex].Base();
+ while (status.Int() == KRequestPending)
+ {
+ User::After(10000);
+ for (TInt8 k = 0; k < 10; k ++)
+ {
+ if (base == gChunkArray1[chunkIndex].Base() + gChunkArray1[chunkIndex].Size())
+ {
+ base = gChunkArray1[chunkIndex].Base();
+ }
+ *base++ = k; // write 0 - 9 to the chunk
+ }
+ }
+
+ User::WaitForRequest(status);
+ r = status.Int();
+ TESTDEBUG(test.Printf(_L("defrag running on another thread returns %d\n"), r));
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Correct return value\n"));
+ test.Printf(_L("Passed...\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+
+ gTestThread.Close();
+ TestEnd();
+
+
+ test.Next(_L("Test2: Whilst moving page, change the contents of the page"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks, KChunkDefaultSize);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+ WriteToChunk(gChunkArray1, gChunkArraySize1, KAllChunks);
+
+ r = gTestThread.Create(gTestThreadName,MultiGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+
+ TUint8 startValue = 0;
+ while (status.Int() == KRequestPending)
+ {
+ User::After(10000);
+ WriteToChunk(gChunkArray1, gChunkArraySize1, KAllChunks, startValue);
+ if (++startValue > 245)
+ {
+ startValue = 0;
+ }
+ }
+
+ User::WaitForRequest(status);
+ r = status.Int();
+ TESTDEBUG(test.Printf(_L("defrag running on another thread returns %d\n"), r));
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Correct return value\n"));
+ test.Printf(_L("Passed...\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+
+ gTestThread.Close();
+ TestEnd();
+
+
+ test.Next(_L("Test3: Whilst moving page, read pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks, KChunkDefaultSize);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+ WriteToChunk(gChunkArray1, gChunkArraySize1, KAllChunks);
+
+ r = gTestThread.Create(gTestThreadName,MultiGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+
+ while (status.Int() == KRequestPending)
+ {
+ User::After(100000000);
+ ReadChunk(gChunkArray1, gChunkArraySize1);
+ }
+
+ User::WaitForRequest(status);
+ r = status.Int();
+ TESTDEBUG(test.Printf(_L("defrag running on another thread returns %d\n"), r));
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Correct return value\n"));
+ test.Printf(_L("Passed...\n"));
+ }
+ else
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+
+ gTestThread.Close();
+ TestEnd();
+
+ test.Next(_L("Test4: Allocate fixed pages and then perform a defrag"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ Ldd.AllocateFixedWrite(FILL_ALL_FIXED);
+
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ test.Printf(_L("defrag returns %d\n"), r);
+
+ if (CheckZonesSwitchedOff() != EFalse)
+ {
+ test.Printf(_L("Fail: Zones were switched off when they shouldn't have been\n"));
+ CLEANUP(r = Ldd.FreeAllFixedPagesRead());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ r = Ldd.FreeAllFixedPagesRead();
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.Next(_L("Test5: Allocate discardable pages and then perform a defrag"));
+ TestStart();
+ if (gPagedRom)
+ {
+ TInt discardablePages;
+
+ UpdateRamInfo();
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ TESTDEBUG(test.Printf(_L("Number of discardable pages = 0x%x\n"), discardablePages >> gPageShift));
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ TESTDEBUG(test.Printf(_L("defrag returns %d\n"), r));
+
+ if (genSucceed && CheckZonesSwitchedOff() == EFalse)
+ {
+ test.Printf(_L("Fail: Zones were not switched off when they should have been\n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ ResetDPCache();
+
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+ test.End();
+ return 0;
+ }
+
+
+//
+// TestMovPgsDefrag
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0527
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the moving of pages in the defrag implmentation
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this perform a RAM defrag.
+//! Now that all movable memory has now been moved and the relevant source
+//! zones have been switched off, again attempt to perform a RAM defrag.
+//! 2. Fragment the memory. Following this perform a RAM defrag and whilst
+//! this is happening, continuously create more chunks.
+//! 3. Set up memory so that there are a mix of movable and free pages in a low preference zone, with there
+//! being movable pages in the higher preference zones. Following this call a general defrag
+//! 4. Set up memory so that there are a mix of movable and free pages and a couple of free pages
+//! in a low preference zone, with there being enough free pages in the higher preference zones for the
+//! pages to be moved to. Following this call a general defrag
+//! 5. Set up memory so that there is a fixed page and a movable page in an empty zone (testZone). Also ensure that
+//! there are movable and free pages in more preferable zones than the test zone. Following this call a general
+//! defrag
+//! 6. Set up memory so that the mostPrefZone contains movable and free pages. Allocate 1 movable and 1 fixed
+//! page into an empty zone (testZone). Following this call a general defrag.
+//!
+//! @SYMTestExpectedResults
+//! 1. Second defrag does not empty any zones
+//! 2. No zones have been emptied
+//! 3. Zones are emptied if the general defrag can succeed
+//! 4. Defrag fills up the less preferable zones first
+//! 5. movable pages are moved from the testZone
+//! 6. testZone is not emptied
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestMovPgsDefrag()
+ {
+ TInt r = KErrNone;
+
+ test.Start(_L("Test1: Performing a defrag twice"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling general defrag r = %d\n"), r));
+
+ r = VerifyMovDisAlloc();
+ // The first defrag should empty zones if the general can succeed
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, memory is not laid out as expected\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ TESTDEBUG(test.Printf(_L("After calling general defrag again r = %d\n"), r));
+
+ // The second call to general defrag should have nothing further to do
+ if (r != KErrNone || CheckZonesSwitchedOff() != EFalse)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d, or zones have been switched off \n"),
+ r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+
+ test.Next(_L("Test2: Ensure new memory allocations can occur successfully during a general defrag"));
+ TestStart();
+
+ // Create a thread to call Defrag continuously and resume it
+ r = gTestThread.Create(gTestThreadName,MultiLoopGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+ gTestLoop = ETrue;
+ gTestThread.Resume();
+
+ // Whilst the defrag loop is taking place, continuously allocate and free memory
+ for (TInt i = 0; i < 100; i++)
+ {
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ if (r != KErrNone)
+ break;
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ }
+ gTestLoop = EFalse;
+ User::WaitForRequest(status);
+ TESTDEBUG(test.Printf(_L("defrag running on another thread returns %d\n"), r));
+
+ if (r != KErrNone || status.Int() != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, status.Int() = %d\n"), r, status.Int());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ gTestThread.Close();
+ TestEnd();
+
+
+ test.Next(_L("Test3: Check whether RAM defrag switches off any zones"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ TESTDEBUG(test.Printf(_L("After calling zone defrag r = %d\n"), r));
+
+ if (r != KErrNone || (genSucceed && CheckZonesSwitchedOff() == EFalse))
+ {
+ test.Printf(_L("Fail: No zones were switched off or r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test4: Verify that a general defrag moves pages to the least preferable RAM zone in use"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ // Get the preference order
+ GetPrefOrder();
+
+ TUint mostPrefIndex = 0;
+ TUint mostPrefArrayIndex = 0;
+ TUint totMov = 0;
+ TUint lastPrefIndex = 0;
+ TUint lastPrefArrayIndex = 0;
+ TUint movPages = 0;
+ TUint movBytes = 0;
+ TUint totFreeInTestZones = 0;
+ TBool zoneNotEmptyOrFull = EFalse;
+
+
+ // Find the first most pref zone that has free pages in it
+ r = FindMostPrefWithFree(mostPrefIndex, &mostPrefArrayIndex);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ goto skipTest4;
+ }
+
+ // Find the next most preferable free zone
+ lastPrefArrayIndex = mostPrefArrayIndex + 1;
+
+ while (lastPrefArrayIndex < gZoneCount &&
+ gZoneUtilArray[gPrefArray[lastPrefArrayIndex]].iFreePages != gZoneUtilArray[gPrefArray[lastPrefArrayIndex]].iPhysPages)
+ {
+ lastPrefArrayIndex++;
+ }
+
+ if (lastPrefArrayIndex >= gZoneCount)
+ {
+ test.Printf(_L("Skipping...\n"));
+ goto skipTest4;
+ }
+
+ // Block all other zones
+ for (TUint prefIndex = lastPrefArrayIndex + 1; prefIndex < gZoneCount; prefIndex++)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ Ldd.SetZoneFlag(gZoneConfigArray[zoneIndex].iZoneId, gZoneConfigArray[zoneIndex].iFlags, NO_ALLOC_FLAG);
+ }
+
+
+ // Zone alloc to fill half of the last zone under test
+ GetAllPageInfo();
+ lastPrefIndex = gPrefArray[lastPrefArrayIndex];
+ r = Ldd.ZoneAllocDiscontiguous(gZoneConfigArray[lastPrefIndex].iZoneId, gZoneUtilArray[lastPrefIndex].iFreePages >> 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate fixed pages r = %d - Skipping...\n"), r);
+ goto skipTest4;
+ }
+
+
+ // Go through the zones under test and determine the number of free pages
+ GetAllPageInfo();
+ for(TUint prefIndex = mostPrefArrayIndex; prefIndex <= lastPrefArrayIndex; prefIndex++)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ totFreeInTestZones += gZoneUtilArray[zoneIndex].iFreePages;
+ }
+
+ // Allocate movable pages to almost fill zones under test
+ movPages = totFreeInTestZones;
+ movBytes = movPages << gPageShift;
+ while (movBytes && AllocMovable(gChunkArray1, gChunkArraySize1, 1, movBytes) != KErrNone)
+ {
+ movBytes -= gPageSize;
+ movPages--;
+ }
+ if (!movBytes)
+ {
+ test.Printf(_L("Failed to allocate 0x%x movable pages - Skipping...\n"), movPages);
+ goto skipTest4;
+ }
+
+
+ // Free the allocated fixed pages
+ Ldd.FreeAllFixedPages();
+
+ // Reset all the flags
+ ResetRamZoneFlags();
+
+ // Check that the most preferable zone still has movable pages in it
+ // and also check that the last zone under test has free pages in it
+ GetAllPageInfo();
+ if (gTotalPageCount.iMovablePages < movPages ||
+ gZoneUtilArray[mostPrefIndex].iAllocMovable == 0 ||
+ gZoneUtilArray[lastPrefIndex].iFreePages == 0)
+ {
+ test.Printf(_L("Setup failed - Skipping...\n"));
+ goto skipTest4;
+ }
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ // Check that defrag allocated the movable from the less preferable to the more preferable
+ GetPrefOrder();
+ totMov = gTotalPageCount.iMovablePages;
+ for(TInt prefIndex = gZoneCount - 1; prefIndex >= 0 ; prefIndex--)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ GetCandList1(zoneIndex);
+ TUint candIndex = 0;
+ for (; candIndex < gZoneCount; candIndex++)
+ {// Check all the zones of this preference
+ TInt zoneIndexCand = gCandList1[candIndex];
+ if (zoneIndexCand == KInvalidCandIndex)
+ {
+ break;
+ }
+ totMov -= gZoneUtilArray[zoneIndexCand].iAllocMovable;
+ if (gZoneUtilArray[zoneIndexCand].iFreePages != gZoneUtilArray[zoneIndexCand].iPhysPages &&
+ gZoneUtilArray[zoneIndexCand].iFreePages != 0)
+ {
+ zoneNotEmptyOrFull = ETrue;
+ }
+ }
+ prefIndex -= candIndex - 1 ;
+
+ if (zoneNotEmptyOrFull && totMov != 0)
+ {
+ test.Printf(_L("FAIL: index = %d free = 0x%x totMov = 0x%x\n"),
+ zoneIndex, gZoneUtilArray[zoneIndex].iFreePages, totMov);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ TEST_FAIL;
+ }
+ }
+
+skipTest4:
+ TestEnd();
+
+
+ test.Next(_L("Test5: Verify that a general defrag tidies up if RAM zone to be emptied contains fixed pages"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ gChunkArray2 = new RChunk;
+ gChunkArraySize2 = 1;
+
+ // find 2 empty zones - put 1 movable in 1 of them and 1 movable and 1 fixed in the other
+ TUint testZoneIndex1;
+ TUint testZoneIndex2;
+ TUint testZoneID2;
+ TUint numFreeInUse = 0;
+
+ r = FindMostPrefEmpty(testZoneIndex1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Skipping...\n"));
+ goto skipTest5;
+ }
+ // Allocate 1 movable page to the test zone
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, testZoneIndex1, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 movable page to zone index %d, r = %d - Skipping...\n"), testZoneIndex1, r);
+ goto skipTest5;
+ }
+
+ r = FindMostPrefEmpty(testZoneIndex2);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Skipping...\n"));
+ goto skipTest5;
+ }
+ // Allocate 1 movable page to the test zone
+ r = ZoneAllocMovable(gChunkArray2, gChunkArraySize2, testZoneIndex2, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 movable page to zone index %d, r = %d - Skipping...\n"), testZoneIndex2, r);
+ goto skipTest5;
+ }
+
+ // Zone alloc to put 1 fixed page last zone under test
+ testZoneID2 = gZoneConfigArray[testZoneIndex2].iZoneId;
+ r = Ldd.ZoneAllocContiguous(testZoneID2, gPageSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 fixed page to zone %d index, r = %d - Skipping...\n"), testZoneIndex2, r);
+ goto skipTest5;
+ }
+
+ // Allocate 2 fixed (as there is 1 in our test zone) to prevent reordering
+ GetAllPageInfo();
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ TUint totImmovable = gZoneUtilArray[index].iAllocFixed + gZoneUtilArray[index].iAllocUnknown ;
+ if (index != testZoneIndex1 &&
+ index != testZoneIndex2 &&
+ gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages &&
+ totImmovable < 2)
+ {
+ r = Ldd.ZoneAllocToMany(index, 2 - totImmovable);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to alloc 0x%x fixed to zone index %d r = %d - Skipping...\n"),
+ 2, index, r);
+ goto skipTest5;
+ }
+ }
+ }
+
+ // Check that the number of free pages in the other in-use zones >= movable pages in test zone
+ GetAllPageInfo();
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (index != testZoneIndex1 &&
+ index != testZoneIndex2 &&
+ gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages)
+ {
+ numFreeInUse += gZoneUtilArray[index].iFreePages;
+ }
+ }
+ if (gZoneUtilArray[testZoneIndex1].iAllocMovable + gZoneUtilArray[testZoneIndex1].iAllocDiscardable +
+ gZoneUtilArray[testZoneIndex2].iAllocMovable + gZoneUtilArray[testZoneIndex2].iAllocDiscardable > numFreeInUse ||
+ gZoneUtilArray[testZoneIndex2].iAllocFixed == 0)
+ {
+ test.Printf(_L("Setup failed - Skipping...\n"));
+ goto skipTest5;
+ }
+
+ // Added extra tracing to debug random failures
+ PrintPageInfo();
+
+ // Call a general defrag
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ // Check that the defrag tidies up
+ GetAllPageInfo();
+ if(gZoneUtilArray[testZoneIndex1].iAllocMovable ||
+ gZoneUtilArray[testZoneIndex2].iAllocMovable)
+ {
+ test.Printf(_L("FAIL: testZoneIndex1(%d): mov orig 0x%x cur 0x%x, testZoneIndex2(%d) mov orig 0x%x cur 0x%x \n"),
+ testZoneIndex1, gOriginalPageCountArray[testZoneIndex1].iAllocMovable, gZoneUtilArray[testZoneIndex1].iAllocMovable,
+ testZoneIndex2, gOriginalPageCountArray[testZoneIndex2].iAllocMovable, gZoneUtilArray[testZoneIndex2].iAllocMovable);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+
+skipTest5:
+ TestEnd();
+
+
+ test.Next(_L("Test6: Verify that a general defrag will not move pages if RAM zone to be emptied contains fixed pages"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ // Find the first most pref zone that has free pages in it
+ r = FindMostPrefWithFree(mostPrefIndex, &mostPrefArrayIndex);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping...\n"));
+ goto skipTest6;
+ }
+
+ // Find the next most preferable free zone
+ lastPrefArrayIndex = mostPrefArrayIndex + 1;
+ while (lastPrefArrayIndex < gZoneCount &&
+ gZoneUtilArray[gPrefArray[lastPrefArrayIndex]].iFreePages != gZoneUtilArray[gPrefArray[lastPrefArrayIndex]].iPhysPages)
+ {
+ lastPrefArrayIndex++;
+ }
+ if (lastPrefArrayIndex >= gZoneCount)
+ {
+ test.Printf(_L("Skipping...\n"));
+ goto skipTest6;
+ }
+
+
+ // Zone alloc to put 1 fixed page last zone under test
+ lastPrefIndex = gPrefArray[lastPrefArrayIndex];
+ r = Ldd.ZoneAllocDiscontiguous(gZoneConfigArray[lastPrefIndex].iZoneId, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 fixed page to zone index %d r = %d - Skipping...\n"), lastPrefIndex, r);
+ goto skipTest6;
+ }
+
+ GetAllPageInfo();
+ if (!gZoneUtilArray[mostPrefIndex].iFreePages)
+ {
+ test.Printf(_L("Not enough space in zone under test mostPrefIndex = %d - Skipping...\n"), mostPrefIndex);
+ goto skipTest6;
+ }
+
+ // Block all zones apart from the last zone under test from allocation
+ for (TUint prefIndex = 0; prefIndex < gZoneCount; prefIndex++)
+ {
+ TUint zoneIndex = gPrefArray[prefIndex];
+ if (zoneIndex != lastPrefIndex)
+ {
+ Ldd.SetZoneFlag(gZoneConfigArray[zoneIndex].iZoneId, gZoneConfigArray[zoneIndex].iFlags, NO_ALLOC_FLAG);
+ }
+ }
+
+ TESTDEBUG(test.Printf(_L("mostPrefIndex = %d lastPrefIndex = %d\n"), mostPrefIndex, lastPrefIndex));
+
+ // Allocate movable pages to the lastPrefZone that will fit into the most pref zone
+ movPages = gZoneUtilArray[mostPrefIndex].iFreePages;
+ movBytes = movPages << gPageShift;
+ while (movBytes && AllocMovable(gChunkArray1, gChunkArraySize1, 1, movBytes) != KErrNone)
+ {
+ movBytes -= gPageSize;
+ }
+ if (!movBytes)
+ {
+ test.Printf(_L("Failed to allocate 0x%x movable pages r = %d - Skipping...\n"), movPages, r);
+ goto skipTest6;
+ }
+
+ // Reset all the flags
+ ResetRamZoneFlags();
+
+
+ // Check that the number of movable pages in the least pref will fit
+ // into the most preferable zone
+ GetAllPageInfo();
+ if (gZoneUtilArray[lastPrefIndex].iAllocMovable > gZoneUtilArray[mostPrefIndex].iFreePages)
+ {
+ test.Printf(_L("Setup failed - Skipping...\n"));
+ PrintPageInfo();
+ goto skipTest6;
+ }
+
+ // Added extra tracing to debug random failures
+ PrintPageInfo();
+
+ // Call a general defrag
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ // Check that the defrag didn't move any pages from the least pref zone
+ GetAllPageInfo();
+ if(gOriginalPageCountArray[lastPrefIndex].iAllocMovable > gZoneUtilArray[lastPrefIndex].iAllocMovable)
+ {
+ test.Printf(_L("FAIL: mostPref(index %d): origMov = 0x%x curMov = 0x%x, lastPref(index %d): origMov = 0x%x curMov = 0x%x \n"),
+ mostPrefIndex, gOriginalPageCountArray[mostPrefIndex].iAllocMovable, gZoneUtilArray[mostPrefIndex].iAllocMovable,
+ lastPrefIndex, gOriginalPageCountArray[lastPrefIndex].iAllocMovable, gZoneUtilArray[lastPrefIndex].iAllocMovable);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+
+skipTest6:
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+//
+// GenDefragTest123Setup
+//
+// Used to set up the memory ready for testing in TestGenDefrag, Test Steps 1, 2, 3 and 4
+//
+// @param aMovAlloc The number of movable pages to allocate.
+// @param aFixAlloc The number of fixed pages to allocate.
+// @param aDisAlloc The number of discardable pages to allocate.
+// @param aMovIndex On return contains the test zone index.
+// @param aNumFreeInUse On return contains the number of free pages in the inuse zones.
+// @param aTestNo The test number that is using this setup.
+//
+TInt GenDefragTest123Setup(TUint aMovAlloc, TUint aFixAlloc, TUint aDisAlloc, TUint& aMovIndex, TUint& aNumFreeInUse, TUint aTestNo)
+ {
+ TInt r = KErrNone;
+ aNumFreeInUse = 0;
+ const TUint KFillUpTo = 5; // Rough estimate of how full the in-use zones should be
+ const TUint KSpaceNeeded = 2;
+ TUint movPrefIndex = 0;
+ if (aTestNo == 4)
+ {// Test 4 we need to look for the LEAST preferable RAM zone which is empty
+ TUint mostPrefIndex;
+ r = FindLeastPrefEmpty(aMovIndex, &movPrefIndex);
+ TInt r2 = FindMostPrefEmpty(mostPrefIndex);
+ if (r != KErrNone || r2 != KErrNone || !gPagedRom ||
+ gZoneConfigArray[aMovIndex].iPref == gZoneConfigArray[mostPrefIndex].iPref)
+ {
+ test.Printf(_L("r %d r2 %d or not a paged ROM or Equal zone preferences- Skipping test step...\n"),
+ r, r2);
+ return KErrGeneral;
+ }
+ }
+ else
+ {// All other tests look the MOST preferable RAM zone which is empty
+ r = FindMostPrefEmpty(aMovIndex, &movPrefIndex);
+ if (r != KErrNone || !gPagedRom)
+ {
+ test.Printf(_L("No suitable RAM zone found or not a paged ROM - Skipping test step...\n"));
+ return KErrGeneral;
+ }
+ }
+
+ // Go through all the in-use zones and check how many free pages there are
+ // Allocate fixed so there is only KFillUpTo pages in each in-use zone to
+ // ensure that the total number of free pages in the in-use zones can fit into
+ // the zone under test
+ GetAllPageInfo();
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages &&
+ gZoneUtilArray[index].iFreePages > KFillUpTo)
+ {
+ r = Ldd.ZoneAllocToMany(index, gZoneUtilArray[index].iFreePages - KFillUpTo);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to alloc 0x%x fixed to zone index %d r = %d - Ending setup...\n"),
+ gZoneUtilArray[index].iFreePages - KFillUpTo, index, r);
+ return KErrGeneral;
+ }
+ }
+ }
+
+ GetAllPageInfo();
+ // If any of the in-use zones doesn't contain any fixed and unknown pages allocate one fixed
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages &&
+ !gZoneUtilArray[index].iAllocFixed && !gZoneUtilArray[index].iAllocUnknown)
+ {
+ r = Ldd.ZoneAllocToMany(index, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to alloc 0x%x fixed to zone index %d r = %d - Ending setup...\n"),
+ 1, index, r);
+ return KErrGeneral;
+ }
+ }
+ }
+
+ GetAllPageInfo();
+ // Check the total number of free pages in the in-use zones
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages)
+ {
+ aNumFreeInUse += gZoneUtilArray[index].iFreePages;
+ }
+ }
+ TESTDEBUG(test.Printf(_L("aNumFreeInUse = 0x%x\n"), aNumFreeInUse));
+
+ test.Printf(_L("aMovIndex = %d\n"), aMovIndex);
+ if (aNumFreeInUse < KSpaceNeeded)
+ {
+ test.Printf(_L("RAM zone to be tested is too full - Skipping test step...\n"));
+ return KErrGeneral;
+ }
+
+
+ // Ensure that there are movable pages in the zone under test
+ // ensuring that there is also room for discardable pages
+ GetAllPageInfo();
+ if (aMovAlloc != 0 && gZoneUtilArray[aMovIndex].iAllocMovable == 0)
+ {
+ // Allocate just aMovAlloc movable pages
+ TUint movPagesAlloc = aMovAlloc;
+ if (aTestNo == 2 || aTestNo == 4)
+ {// Tests 2 and 4 require that movable pages can't be moved from zone
+ movPagesAlloc = aNumFreeInUse + 1;
+ if (movPagesAlloc > gZoneUtilArray[aMovIndex].iFreePages)
+ {
+ test.Printf(_L("Insufficiant space in zone %d to allocate 0x%x pages - Ending setup...\n"),
+ aMovIndex, movPagesAlloc);
+ return KErrGeneral;
+ }
+ }
+
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, aMovIndex, movPagesAlloc);
+ if (gZoneUtilArray[aMovIndex].iAllocMovable != movPagesAlloc ||
+ gZoneUtilArray[aMovIndex].iFreePages == 0 ||
+ r != KErrNone)
+ {// Movable page didn't go into RAM, or RAM zone is full.
+ test.Printf(_L("Can't complete test with current RAM layout. - Skipping...\n"));
+ test.Printf(_L("zone mov 0x%x free 0x%x r=%d\n"),
+ gZoneUtilArray[aMovIndex].iAllocMovable,
+ gZoneUtilArray[aMovIndex].iFreePages, r);
+ return KErrGeneral;
+ }
+ }
+
+ // Block all other zones from allocation
+ for(TUint i = 0; i < gZoneCount; i++)
+ {
+ if (i != aMovIndex)
+ {
+ r = Ldd.SetZoneFlag(gZoneConfigArray[i].iZoneId, gZoneConfigArray[i].iFlags, NO_ALLOC_FLAG);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set flag on zone index %d r = %d- Ending setup...\n"), i, r);
+ return KErrGeneral;
+ }
+ }
+ }
+
+ // Now ensure that there are fixed pages in the zone under test
+ // ensuring that there is also room for discardable pages
+ GetAllPageInfo();
+ if (aFixAlloc != 0 && gZoneUtilArray[aMovIndex].iAllocFixed == 0)
+ {//Allocate just aFixAlloc fixed pages
+ r = Ldd.ZoneAllocToMany(aMovIndex, aFixAlloc);
+ GetAllPageInfo();
+ if (gZoneUtilArray[aMovIndex].iAllocMovable == 0 ||
+ gZoneUtilArray[aMovIndex].iFreePages == 0 ||
+ gZoneUtilArray[aMovIndex].iAllocFixed == 0 ||
+ r != KErrNone)
+ {// Fixed page didn't go into RAM or RAM zone is full.
+ test.Printf(_L("Can't complete test with current RAM layout. - Skipping...\n"));
+ test.Printf(_L("zone mov 0x%x fixed 0x%x free 0x%x r=%d\n"),
+ gZoneUtilArray[aMovIndex].iAllocMovable,
+ gZoneUtilArray[aMovIndex].iAllocFixed,
+ gZoneUtilArray[aMovIndex].iFreePages, r);
+ return KErrGeneral;
+ }
+ }
+
+
+
+ // Allocate aDisAlloc number of discardable pages
+ if (aDisAlloc != 0 && gZoneUtilArray[aMovIndex].iAllocDiscardable == 0)
+ {//Allocate just aDisAlloc discardable pages
+ TInt discard;
+ r = ZoneAllocDiscard(aMovIndex, aDisAlloc, discard);
+ GetAllPageInfo();
+ if (r != KErrNone || gZoneUtilArray[aMovIndex].iAllocDiscardable == 0)
+ {// Discardable page didn't go into RAM or RAM zone is full.
+ test.Printf(_L("Can't complete test with current RAM layout. - Skipping...\n"));
+ test.Printf(_L("zone mov 0x%x discardable 0x%x free 0x%x r=%d\n"),
+ gZoneUtilArray[aMovIndex].iAllocDiscardable,
+ gZoneUtilArray[aMovIndex].iAllocFixed,
+ gZoneUtilArray[aMovIndex].iFreePages, r);
+ return KErrGeneral;
+ }
+ }
+
+ // Update the total number of free pages in the in-use zones
+ aNumFreeInUse = 0;
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages &&
+ index != aMovIndex)
+ {
+ aNumFreeInUse += gZoneUtilArray[index].iFreePages;
+ }
+ }
+ TESTDEBUG(test.Printf(_L("aNumFreeInUse = 0x%x\n"), aNumFreeInUse));
+
+ // now reset all the flags
+ ResetRamZoneFlags();
+
+ return KErrNone;
+ }
+//
+// TestGenDefrag
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0528
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying general scenarios when RAM defrag would take place
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Allocate 1 movable, 1 fixed and 1 discardable pages into the most preferable empty RAM zone
+//! ensuring that there is enough free space in the more preferable RAM zones for the
+//! movable pages in the RAM zone under test. Following this call a general defrag.
+//! 2. Allocate 1 movable and 1 discardable page into into the most preferable empty RAM zone
+//! ensuring that there is not enough free space in the more preferable RAM zones for the
+//! movable pages in the RAM zone under test. Following this call a general defrag.
+//! 3. Allocate 1 movable and 1 discardable and 1 fixed page into the most preferable empty RAM zone(a).
+//! Following this, place 1 movable page in an empty zone(b) ensuring that there is enough free space in
+//! the more preferable RAM zones for the movable pages in both zones (a) and (b).
+//! Following this call a general defrag.
+//! 4. Allocate 1 movable and 1 discardable page into the least preferable empty RAM zone
+//! ensuring that there is not enough free space in the more preferable RAM zones for the
+//! movable pages in the RAM zone under test. Following this call a general defrag.
+//! 5. Fragment the memory.
+//! Following this allocate discardable pages by loading pages that are demand paged.
+//! Read each of the constants from beginning to end.
+//! Following this perform a RAM defrag.
+//! 6. Call a device driver that will continuously allocate fixed pages to the
+//! memory until it reports out of memory. Following this perform a RAM defrag.
+//! 7. Defrag memory filled with discardable pages when the min cache size is reached
+//! 8. Fragment the memory. Following this, continuously call a general defrag, each time
+//! reducing the size of the chunks that are allocated
+//!
+//! @SYMTestExpectedResults
+//! 1. The RAM zone under test is not emptied and all the discardable pages contained in it
+//! have not been discarded.
+//! 2. The RAM zone under test is not emptied and all the discardable pages contained in it
+//! have not been discarded.
+//! 3. RAM zones (a) and (b) have been emptied and all the discardable pages contained in them
+//! have not been discarded.
+//! 4. The RAM zone under test is emptied
+//! 5. Pages are discarded
+//! 6. No zones are emptied
+//! 7. The least preferable zone is skipped but the other zones are defragmented as required.
+//! 8. Zones are emptied if the general defrag can succeed
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestGenDefrag()
+ {
+ TInt r = KErrNone;
+
+ test.Start(_L("Test1: Test General Defrag doesn't discard pages when fixed page in zone to be emptied"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ TUint numFreeInUse = 0;
+ TUint testNo = 1;
+
+ // We just need 1 movable, 1 discardable and 1 fixed in the zone to ensure it cannot be emptied
+ // as the fixed should block the defrag
+ TInt movAllocPages = 1;
+ TInt fixAllocPages = 1;
+ TInt disAllocPages = 1;
+ TUint zoneIndex;
+
+ if (GenDefragTest123Setup(movAllocPages, fixAllocPages, disAllocPages, zoneIndex, numFreeInUse, testNo) != KErrNone)
+ {
+ test.Printf(_L("Setup failed - Skipping..\n"));
+ goto skipTest1;
+ }
+
+ // Call a general defrag and check that no discardable pages were freed.
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndex].iAllocMovable < gOriginalPageCountArray[zoneIndex].iAllocMovable ||
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable > gZoneUtilArray[zoneIndex].iAllocDiscardable)
+ {
+ test.Printf(_L("Fail: r = %d zoneIndex %d origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"), r, zoneIndex,
+ gOriginalPageCountArray[zoneIndex].iAllocMovable, gZoneUtilArray[zoneIndex].iAllocMovable,
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable, gZoneUtilArray[zoneIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+skipTest1:
+ // TestEnd() will perform any required clean up.
+ TestEnd();
+
+ test.Next(_L("Test2: Test General Defrag doesn't discard pages when zone can't be emptied"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ testNo++;
+ // No fixed, but there should be no space for the movable to go to
+ // GenDefragTest123Setup(), will ensure that this is the case
+ // by allocating 1 more movable page than there is free in the in-use zones
+ movAllocPages = 1;
+ fixAllocPages = 0;
+ disAllocPages = 1;
+
+ if (GenDefragTest123Setup(movAllocPages, fixAllocPages, disAllocPages, zoneIndex, numFreeInUse, testNo) != KErrNone)
+ {
+ test.Printf(_L("Setup failed - Skipping..\n"));
+ goto skipTest2;
+ }
+
+ // Call a general defrag and check that no discardable pages were freed.
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndex].iAllocMovable < gOriginalPageCountArray[zoneIndex].iAllocMovable ||
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable > gZoneUtilArray[zoneIndex].iAllocDiscardable)
+ {
+ test.Printf(_L("Fail: r = %d zoneIndex %d origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"), r, zoneIndex,
+ gOriginalPageCountArray[zoneIndex].iAllocMovable, gZoneUtilArray[zoneIndex].iAllocMovable,
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable, gZoneUtilArray[zoneIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+skipTest2:
+ // TestEnd() will perform any required clean up.
+ TestEnd();
+
+ test.Next(_L("Test3: Test General Defrag tidies when fixed page in zone to be emptied but other can be emptied"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ gChunkArray2 = new RChunk;
+ gChunkArraySize2 = 1;
+ TUint totalToMove;
+ testNo++;
+
+ // First use GenDefragTest123Setup() to ensure we place 1 fixed, 1 movable and 1 discardable
+ // in the least preferable zone
+ movAllocPages = 1;
+ fixAllocPages = 1;
+ disAllocPages = 1;
+ TBool zoneFound = EFalse;
+ TUint emptyZoneIndex = 0;
+
+ if (GenDefragTest123Setup(movAllocPages, fixAllocPages, disAllocPages, zoneIndex, numFreeInUse, testNo) != KErrNone)
+ {
+ test.Printf(_L("Setup failed - Skipping..\n"));
+ goto skipTest3;
+ }
+
+ // Find an empty zone and place a movable page in it
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gZoneUtilArray[i].iFreePages == gZoneUtilArray[i].iPhysPages)
+ {
+ zoneFound = ETrue;
+ emptyZoneIndex = i;
+ break;
+ }
+ }
+ if (!zoneFound)
+ {
+ test.Printf(_L("Can't find empty zone - Skipping..\n"));
+ goto skipTest3;
+ }
+
+ // Allocate 1 movable page into the empty zone
+ r = ZoneAllocMovable(gChunkArray2, gChunkArraySize2, emptyZoneIndex, 1);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[emptyZoneIndex].iAllocMovable == 0 ||
+ gZoneUtilArray[emptyZoneIndex].iAllocFixed != 0)
+ {
+ test.Printf(_L("Movable pages not allocated or fixed pages allocated. - Skipping...\n"));
+ test.Printf(_L("zone mov 0x%x free 0x%x r =% d\n"),
+ gZoneUtilArray[emptyZoneIndex].iAllocMovable,
+ gZoneUtilArray[emptyZoneIndex].iFreePages, r);
+ goto skipTest3;
+ }
+
+ // Check that the amount we are allocating can actually be moved into the in-use zones
+ totalToMove = gZoneUtilArray[zoneIndex].iAllocMovable + gZoneUtilArray[zoneIndex].iAllocDiscardable +
+ gZoneUtilArray[emptyZoneIndex].iAllocMovable + gZoneUtilArray[emptyZoneIndex].iAllocDiscardable;
+
+ // Check the total number of free pages in the in-use zones
+ numFreeInUse = 0;
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages != gZoneUtilArray[index].iPhysPages &&
+ index != zoneIndex && index != emptyZoneIndex)
+ {
+ numFreeInUse += gZoneUtilArray[index].iFreePages;
+ }
+ }
+ if(numFreeInUse < totalToMove)
+ {
+ test.Printf(_L("No space to move pages numFreeInUse = 0x%x totalToMove = 0x%x - Skipping..\n"),
+ numFreeInUse, totalToMove);
+ goto skipTest3;
+ }
+
+ // Call a general defrag and check that zone is emptied.
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndex].iAllocMovable ||
+ gZoneUtilArray[zoneIndex].iAllocDiscardable ||
+ gZoneUtilArray[emptyZoneIndex].iAllocMovable)
+ {
+ test.Printf(_L("Fail: r = %d zoneIndex %d origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"), r, zoneIndex,
+ gOriginalPageCountArray[zoneIndex].iAllocMovable, gZoneUtilArray[zoneIndex].iAllocMovable,
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable, gZoneUtilArray[zoneIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+skipTest3:
+ // TestEnd() will perform any required clean up.
+ TestEnd();
+
+ test.Next(_L("Test4: Test General Defrag moves pages into the next most pref if they don't fit into the most pref"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ testNo++;
+
+ // No fixed, but there should be no space for the movable to go to
+ // GenDefragTest123Setup(), will ensure that this is the case
+ // by allocating 1 more movable page than there is free in the in-use zones
+ movAllocPages = 1;
+ fixAllocPages = 0;
+ disAllocPages = 1;
+
+ if (GenDefragTest123Setup(movAllocPages, fixAllocPages, disAllocPages, zoneIndex, numFreeInUse, testNo) != KErrNone)
+ {
+ test.Printf(_L("Setup failed - Skipping..\n"));
+ goto skipTest4;
+ }
+
+ // Call a general defrag and check that the test zone is emptied.
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndex].iFreePages != gZoneUtilArray[zoneIndex].iPhysPages)
+ {
+ test.Printf(_L("Fail: r = %d zoneIndex %d origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"), r, zoneIndex,
+ gOriginalPageCountArray[zoneIndex].iAllocMovable, gZoneUtilArray[zoneIndex].iAllocMovable,
+ gOriginalPageCountArray[zoneIndex].iAllocDiscardable, gZoneUtilArray[zoneIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+skipTest4:
+ // TestEnd() will perform any required clean up.
+ TestEnd();
+
+ test.Next(_L("Test5: Defrag memory filled with discardable pages\n"));
+ TestStart();
+ if (gPagedRom)
+ {
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TInt discardablePages;
+ UpdateRamInfo();
+
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ TESTDEBUG(test.Printf(_L("Number of discardable pages = 0x%x\n"), discardablePages >> gPageShift));
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"),r,KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else if (genSucceed && CheckZonesSwitchedOff() == EFalse)
+ {
+ test.Printf(_L("No Zones Switched off and should have been\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ ResetDPCache();
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test6: Defrag memory filled with fixed pages"));
+ TestStart();
+
+ TESTDEBUG(test.Printf(_L("Filling memory with fixed pages, r = %d\n")));
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+
+ // The zones should be full of fixed pages so the general should do nothing.
+ if (r != KErrNone ||
+ genSucceed ||
+ CheckZonesSwitchedOff())
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d, or zone have been emptied\n"), r, KErrNone);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ Ldd.FreeAllFixedPages();
+ TestEnd();
+
+ test.Next(_L("Test7: Defrag memory filled with discardable pages when the min cache size is reached\n"));
+ TestStart();
+ if (gPagedRom)
+ {
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TInt discardablePages;
+ UpdateRamInfo();
+
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ TESTDEBUG(test.Printf(_L("Number of discardable pages = 0x%x\n"), discardablePages >> gPageShift));
+
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+
+ TUint setMin = maxCacheSize;
+ TUint64 setMax = maxCacheSize;
+ TInt r = DPTest::SetCacheSize(setMin, setMax);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ TESTDEBUG(test.Printf(_L("After SetCacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x\n"),
+ setMin >> gPageShift, setMax >> gPageShift));
+
+ GetOriginalPageCount();
+ genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"),r,KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else if (genSucceed && CheckZonesSwitchedOff() == EFalse)
+ {
+ test.Printf(_L("No Zones Switched off and should have been\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ ResetDPCache();
+
+
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test8: Defrag fragmented memory for various smaller chunk sizes"));
+ TInt chunkSize = 0x80000;
+ while (chunkSize >= 0x4000)
+ {
+ test.Printf(_L("chunkSize = %dKB\n"), chunkSize/1024);
+ TestStart();
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable, chunkSize, EFalse);
+ r = FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"),r,KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else if (genSucceed && CheckZonesSwitchedOff() == EFalse)
+ {
+ test.Printf(_L("No Zones Switched off and should have been\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+ chunkSize = chunkSize>>1;
+ }
+
+ test.Next(_L("Test9: Defrag fragmented memory "));
+ TestStart();
+
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable);
+ r = FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetOriginalPageCount();
+ genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"),r,KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else if (genSucceed && CheckZonesSwitchedOff() == EFalse)
+ {
+ test.Printf(_L("No Zones Switched off and should have been\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestGetRamZonePageCount
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0529
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the implementation of the function GetRamZonePageCount()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this, call GetRamZonePageCount() on every zone and verify
+//! the values with the test HAL functions.
+//! 2. Fragment the memory. Following this, call function with an valid aID
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//! 2. KErrArgument
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestGetRamZonePageCount()
+ {
+ test.Start(_L("Test1: Call GetRamZonePageCount() on every zone one after the other"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ GetAllPageInfo();
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+
+ STestUserSidePageCount pageData;
+ TInt r = Ldd.PageCount(zoneID, &pageData);
+ TESTDEBUG(test.Printf(_L("Page count function r = %d\n"), r));
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ if (pageData.iFreePages != gZoneUtilArray[index].iFreePages ||
+ pageData.iFixedPages != gZoneUtilArray[index].iAllocFixed ||
+ pageData.iMovablePages != gZoneUtilArray[index].iAllocMovable ||
+ pageData.iDiscardablePages != gZoneUtilArray[index].iAllocDiscardable)
+ {
+ test.Printf(_L("RAM zone page count does not match test HAL page count, Zone %d\n"), zoneID);
+ test.Printf(_L("PgCnt: free = 0x%x, fixed = 0x%x, movable= 0x%x, discard = 0x%x\n"),
+ pageData.iFreePages, pageData.iFixedPages, pageData.iMovablePages, pageData.iDiscardablePages);
+ test.Printf(_L("HalFunc: free = 0x%x, fixed = 0x%x, movable= 0x%x, discard = 0x%x\n"),
+ gZoneUtilArray[index].iFreePages, gZoneUtilArray[index].iAllocFixed,
+ gZoneUtilArray[index].iAllocMovable, gZoneUtilArray[index].iAllocDiscardable);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Zone %d Passed...\n"), zoneID);
+ }
+ TESTDEBUG(test.Printf(_L("iFreePages = 0x%x, iFixedPages = 0x%x, iMovablePages = 0x%x, iDiscardablePages = 0x%x\n"),
+ pageData.iFreePages, pageData.iFixedPages, pageData.iMovablePages, pageData.iDiscardablePages));
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.Next(_L("Test2: Call GetRamZonePageCount() with an invalid aID "));
+ TestStart();
+
+ TUint zoneID = KInvalidZoneID;
+ STestUserSidePageCount pageData;
+ TInt r = Ldd.PageCount(zoneID, &pageData);
+ TESTDEBUG(test.Printf(_L("Page count function r = %d\n"), r));
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ TestEnd();
+
+ test.End();
+ return 0;
+ }
+
+const TUint KIndex2Alloc = 10;
+const TUint KTestMaxPages = 6;
+
+//
+// DefragMaxPagesSetup
+//
+// Arranges the memory layout in preparation for TestDefragRamMaxPages()
+//
+// WARNING THIS WILL BE UNRELIABLE IF aMaxPages > KIndex2Alloc
+//
+TInt DefragMaxPagesSetup(TInt aPageType, TUint aMaxPages, TUint& aIndex, TUint& aIndex2)
+ {
+ TInt r = KErrNoMemory;
+
+ // Get the preference order and determine the 2 most preferable zones
+ // that are currently not in use.
+ GetPrefOrder();
+ TUint freeInUsePages = 0;
+ TBool zonesFound = EFalse;
+ for (TUint i = 1; i < gZoneCount; i++)
+ {
+ aIndex = gPrefArray[i];
+ aIndex2 = gPrefArray[i-1];
+ TUint indexFree = gZoneUtilArray[aIndex].iFreePages;
+ TUint index2Free = gZoneUtilArray[aIndex2].iFreePages;
+ if (indexFree == gZoneUtilArray[aIndex].iPhysPages &&
+ index2Free == gZoneUtilArray[aIndex2].iPhysPages &&
+ indexFree >= aMaxPages && index2Free >= KIndex2Alloc &&
+ freeInUsePages >= KIndex2Alloc + aMaxPages)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ freeInUsePages += index2Free;
+ }
+
+ // Could suitable RAM zones be found.
+ if (!zonesFound)
+ {
+ test.Printf(_L("Insufficient memory - Skipping test...\n"));
+ return KErrNoMemory;
+ }
+
+ if (aPageType == BEST_MOVABLE)
+ {
+ // Allocate KIndex2Alloc movable pages to aIndex2
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, aIndex2, KIndex2Alloc);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Insufficient memory - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+
+
+
+ // Now allow movable pages to be allocated into the least preferable RAM zone under test only.
+ GetAllPageInfo();
+ if (aMaxPages >= gZoneUtilArray[aIndex].iFreePages)
+ {
+ test.Printf(_L("Insufficient memory available - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+ // Allocate aMaxPages movable pages to aIndex
+ r = ZoneAllocMovable(gChunkArray2, gChunkArraySize2, aIndex, aMaxPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Insufficient memory - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+
+ // Determine how many free pages there are in the RAM zones more preferable
+ // than the RAM zones under test.
+ GetPrefOrder();
+ freeInUsePages = 0;
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ TUint tmpIndex = gPrefArray[i];
+ if (tmpIndex == aIndex2)
+ break;
+ freeInUsePages += gZoneUtilArray[tmpIndex].iFreePages;
+ }
+ // Verify that the RAM layout is still suitable for the test.
+ if (gZoneUtilArray[aIndex].iAllocMovable != aMaxPages ||
+ gZoneUtilArray[aIndex2].iAllocMovable != KIndex2Alloc ||
+ gZoneUtilArray[aIndex].iAllocDiscardable || gZoneUtilArray[aIndex].iAllocFixed ||
+ gZoneUtilArray[aIndex2].iAllocDiscardable || gZoneUtilArray[aIndex2].iAllocFixed ||
+ freeInUsePages < KIndex2Alloc + aMaxPages)
+ {
+ test.Printf(_L("Insufficient memory - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+
+ // now reset all the flags
+ ResetRamZoneFlags();
+
+ // Perform a general defrag
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, KTestMaxPages);
+ goto exit;
+ }
+
+ if (aPageType == BEST_DISCARDABLE)
+ {
+
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift);
+
+
+
+ // Allocate a number of discardable pages to the 2nd least preferable zone under test
+ TInt disPages;
+ r = ZoneAllocDiscard(aIndex2, KIndex2Alloc, disPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("ZoneAllocDiscard() r = %d KIndex2Alloc = 0x%x disPages = 0x%x aIndex2 = %d - Skipping test...\n"),
+ r, KIndex2Alloc, disPages, aIndex2);
+ GetAllPageInfo();
+ PrintPageInfo();
+ r = KErrNoMemory;
+ goto error;
+ }
+ TUint discFillBytes = KIndex2Alloc << gPageShift;
+ r = DPTest::SetCacheSize(currentCacheSize + discFillBytes, currentCacheSize + discFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("SetCacheSize r = 0x%x currentCacheSize + discFillBytes = 0x%x - Skipping test...\n"),
+ r, currentCacheSize + discFillBytes);
+ GetAllPageInfo();
+ PrintPageInfo();
+ r = KErrNoMemory;
+ goto error;
+ }
+
+
+ // Allocate a discardable pages equal to aMaxPages to the least preferable zone under test
+ GetAllPageInfo();
+ if(aMaxPages >= gTotalPageCount.iFreePages)
+ {
+ test.Printf(_L("Insufficient memory available - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+ TUint allocPages = aMaxPages + KIndex2Alloc;
+ r = ZoneAllocDiscard(aIndex, aMaxPages, disPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("ZoneAllocDiscard() r = %d aMaxPages = 0x%x disPages = 0x%x aIndex = %d - Skipping test...\n"),
+ r, aMaxPages, disPages, aIndex);
+ GetAllPageInfo();
+ PrintPageInfo();
+ r = KErrNoMemory;
+ goto error;
+ }
+ discFillBytes = allocPages << gPageShift;
+ r = DPTest::SetCacheSize(currentCacheSize + discFillBytes, currentCacheSize + discFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("SetCacheSize r = %d currentCacheSize + discFillBytes = 0x%x - Skipping test...\n"),
+ r, currentCacheSize + discFillBytes);
+ GetAllPageInfo();
+ PrintPageInfo();
+ r = KErrNoMemory;
+ goto error;
+ }
+
+
+ // Determine how many free pages there are in the RAM zones more preferable
+ // than the RAM zones under test.
+ GetPrefOrder();
+ freeInUsePages = 0;
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ TUint tmpIndex = gPrefArray[i];
+ if (tmpIndex == aIndex2)
+ break;
+ freeInUsePages += gZoneUtilArray[tmpIndex].iFreePages;
+ }
+ // Verify that the RAM layout is still suitable for the test.
+ if (r != KErrNone || gZoneUtilArray[aIndex].iAllocDiscardable != aMaxPages ||
+ gZoneUtilArray[aIndex2].iAllocDiscardable != KIndex2Alloc ||
+ gZoneUtilArray[aIndex].iAllocMovable || gZoneUtilArray[aIndex].iAllocFixed ||
+ gZoneUtilArray[aIndex2].iAllocMovable || gZoneUtilArray[aIndex2].iAllocFixed ||
+ freeInUsePages < KIndex2Alloc + aMaxPages)
+ {
+ test.Printf(_L("Insufficient memory - Skipping test...\n"));
+ r = KErrNoMemory;
+ goto error;
+ }
+
+ // now reset all the flags
+ ResetRamZoneFlags();
+
+ // Perform a general defrag with maxPages = KTestMaxPages
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, KTestMaxPages);
+ goto exit;
+
+ }
+error:
+ // Reset all the flags
+ ResetRamZoneFlags();
+exit:
+ return r;
+ }
+
+//
+// TestDefragRamMaxPages
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0530
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the implementation of the function TRamDefragRequest::DefragRam()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Call function with invalid aMaxPages
+//! 2. Call DefragRam when aMaxPages < number of movable pages in least preferable zone
+//! 3. Call DefragRam when aMaxPages > number of movable pages in least preferable zone
+//! 4. Call DefragRam when aMaxPages = number of movable pages in least preferable zone
+//! 5. Call DefragRam when aMaxPages < number of discardable pages in least preferable zone
+//! 6. Call DefragRam when aMaxPages > number of discardable pages in least preferable zone
+//! 7. Call DefragRam when aMaxPages = number of discardable pages in least preferable zone
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrArgument
+//! 2. Least preferable zone and 2nd least preferable zone have not been emptied
+//! 3. Least preferable zone has been emptied and 2nd least preferable zone has not been emptied
+//! 4. Least preferable zone has been emptied and 2nd least preferable zone not not been emptied
+//! 5. Least preferable zone and 2nd least preferable zone have not been emptied
+//! 6. Least preferable zone has been emptied and 2nd least preferable zone has not been emptied
+//! 7. Least preferable zone has been emptied and 2nd least preferable zone not not been emptied
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestDefragRamMaxPages()
+ {
+ test.Start(_L("Test1: Call DefragRam with invalid aMaxPages "));
+ TestStart();
+
+ gDefragMaxPages = -1;
+
+ TInt r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+ TESTDEBUG(test.Printf(_L("After calling defrag r = %d\n"), r));
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test2: Call DefragRam aMaxPages < number of movable pages in least preferable zone "));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ gChunkArray2 = new RChunk;
+ gChunkArraySize2 = 1;
+ TUint index = 0;
+ TUint index2 = 0;
+ r = DefragMaxPagesSetup(BEST_MOVABLE, KTestMaxPages + 1, index, index2);
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable < KTestMaxPages + 1 ||
+ gZoneUtilArray[index2].iAllocMovable < KIndex2Alloc)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, KTestMaxPages + 1, index2, KIndex2Alloc);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ // if there is free space elsewhere
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+ GetAllPageInfo();
+ if (gTotalPageCount.iFreePages > KIndex2Alloc + KTestMaxPages + 1 &&
+ (gZoneUtilArray[index].iAllocMovable != 0 || gZoneUtilArray[index2].iAllocMovable != 0))
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ }
+ Ldd.FreeFromAllZones();
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call DefragRam aMaxPages > number of movable pages in least preferable zone "));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ gChunkArray2 = new RChunk;
+ gChunkArraySize2 = 1;
+ r = DefragMaxPagesSetup(BEST_MOVABLE, KTestMaxPages - 1, index, index2);
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable != 0)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, KIndex2Alloc);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ // if there is free space elsewhere
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+
+ GetAllPageInfo();
+ if (gTotalPageCount.iFreePages > KIndex2Alloc + KTestMaxPages - 1 &&
+ (gZoneUtilArray[index].iAllocMovable != 0 || gZoneUtilArray[index2].iAllocMovable != 0))
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ }
+ Ldd.FreeFromAllZones();
+ TestEnd();
+
+
+ test.Next(_L("Test4: Call DefragRam aMaxPages = number of movable pages in least preferable zone "));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ gChunkArray2 = new RChunk;
+ gChunkArraySize2 = 1;
+ r = DefragMaxPagesSetup(BEST_MOVABLE, KTestMaxPages, index, index2);
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable != 0)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, KIndex2Alloc);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ // if there is free space elsewhere
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+
+ GetAllPageInfo();
+ if (gTotalPageCount.iFreePages > KIndex2Alloc + KTestMaxPages &&
+ (gZoneUtilArray[index].iAllocMovable != 0 || gZoneUtilArray[index2].iAllocMovable != 0))
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(RemoveChunkAlloc(gChunkArray2, gChunkArraySize2));
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ RemoveChunkAlloc(gChunkArray2, gChunkArraySize2);
+ }
+ Ldd.FreeFromAllZones();
+ TestEnd();
+
+ test.Next(_L("Test5: Call DefragRam aMaxPages < number of discardable pages in least preferable zone "));
+ TestStart();
+ if (gPagedRom)
+ {
+ r = DefragMaxPagesSetup(BEST_DISCARDABLE, KTestMaxPages + 1, index, index2);
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable < KTestMaxPages + 1 ||
+ gZoneUtilArray[index2].iAllocDiscardable < KIndex2Alloc)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, KTestMaxPages + 1, index2, KIndex2Alloc);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0 ||
+ gZoneUtilArray[index2].iAllocDiscardable != 0)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+ ResetDPCache();
+ }
+ Ldd.FreeFromAllZones();
+ }
+ else
+ {
+ test.Printf(_L("Not a Paged Rom - Skipping...\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test6: Call DefragRam aMaxPages > number of discardable pages in least preferable zone "));
+ TestStart();
+
+ if (gPagedRom)
+ {
+ r = DefragMaxPagesSetup(BEST_DISCARDABLE, KTestMaxPages - 1, index, index2);
+
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0||
+ gZoneUtilArray[index2].iAllocDiscardable != KIndex2Alloc)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, KIndex2Alloc);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0||
+ gZoneUtilArray[index2].iAllocDiscardable != 0)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+ ResetDPCache();
+ }
+ Ldd.FreeFromAllZones();
+ }
+ else
+ {
+ test.Printf(_L("Not a Paged Rom - Skipping...\n"));
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test4: Call DefragRam aMaxPages = number of discardable pages in least preferable zone "));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DefragMaxPagesSetup(BEST_DISCARDABLE, KTestMaxPages, index, index2);
+
+ if (gZoneUtilArray[index].iAllocFixed > 0 || gZoneUtilArray[index2].iAllocFixed > 0)
+ {// Cannot perform test with fixed pages in least preferable zones
+ test.Printf(_L("Fixed pages in least preferable zone - Skipping...\n"));
+ }
+ else
+ {
+ if (r == KErrNone)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0||
+ gZoneUtilArray[index2].iAllocDiscardable != KIndex2Alloc)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, KIndex2Alloc);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+
+ // Double check that if DefragRam is called with maxPages = 0, these zones are emptied
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0||
+ gZoneUtilArray[index2].iAllocDiscardable != 0)
+ {
+ test.Printf(_L("Fail: index = %d, expected = 0x%x, index2 = %d, expected = 0x%x\n"),
+ index, 0, index2, 0);
+ CLEANUP(ResetDPCache());
+ CLEANUP(Ldd.FreeFromAllZones());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("DefragMaxPagesSetup failed r = %d\n"), r);
+ }
+ ResetDPCache();
+ }
+ Ldd.FreeFromAllZones();
+ }
+ else
+ {
+ test.Printf(_L("Not a Paged Rom - Skipping...\n"));
+ }
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestEmptyRamZone
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0531
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the implementation of the function TRamDefragRequest::EmptyRamZone()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Call function with a valid aID,
+//! i.e. a zone which lies within the range of zones.
+//! 2. Fragment the memory. Call function with an invalid aID
+//! i.e. a zone which does not exist within the range of zones.
+//! 3. Fragment the memory. Following this, call a zone specific defrag on a particular zone.
+//! Call the zone specific defrag again on the same zone whilst the other defrag is still
+//! running on that zone.
+//! 4. Fragment the memory. Following this, call the TRamDefragRequest::DefragRam() to perform general defrag.
+//! Following this call zone specific defrag whilst the general defrag is still running.
+//! 5. Fragment the memory. Following this, call a zone specific defrag on a particular zone.
+//! Whilst the zone defrag is running, call a general defrag
+//! 6: Fragment the memory. Following this, call the function on specifc zone and
+//! at the same time allocate pages to the zone
+//! 7. Fragment the memory. Call EmptyRamZone() on every zone one after the other.
+//! 8. Fragment the memory. Allocate a couple of fixed pages to a zone that contains movable pages.
+//! Following this, Call EmptyRamZone() on that zone.
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//! 2. KErrArgument
+//! 3. KErrNone and the zone has been emptied
+//! 4. Zone has not been emptied, as the general defrag has already placed pages in the zone
+//! 5. Zone has been emptied
+//! 6. KErrNone and pages have been allocated in the zone
+//! 7. One of the following scenarios should occur:
+//! a. If the cache has not reached its minimum size, then all the movable pages should
+//! be moved from the zone if there are enough free pages in the other zones.
+//! However, when demand paging is off, all movable pages should be moved from the zone, again if there
+//! are enough free pages in the other zones.
+//! b. If the current size of the cache minus the number of discardable pages in the zone being emptied is
+//! not less than the minimum cache size, then all the discardable pages should be discarded of.
+//! However, when demand paging is off, all discardable pages should be removed from
+//! the zone.
+//! 8. KErrNoMemory, however all movable and discardable pages have been moved from the zone
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestEmptyRamZone()
+ {
+ TInt r = KErrNone;
+ TInt r2 = KErrNone;
+
+ test.Start(_L("Test1: Call EmptyRamZone with valid aID "));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ TUint defragZoneID = gZoneConfigArray[index].iZoneId;
+ test.Printf(_L("Zone ID = %d\n"), defragZoneID);
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, defragZoneID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && (r != KErrNone || !CheckZoneIsOff(index)))
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call EmptyRamZone with invalid aID "));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ defragZoneID = KInvalidZoneID;
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, defragZoneID);
+
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call EmptyRamZone twice at the same time "));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = gTestThread.Create(gTestThreadName,MultiEmptyZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny *)defragZoneID);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+
+ User::After(10);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, defragZoneID);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (r != r2 ||
+ (freeInOthers && (r != KErrNone || r2 != KErrNone || !CheckZoneIsOff(index))))
+ {
+ test.Printf(_L("Fail: r = %d, r2 = %d, expected = %d, or zone %d has not been emptied\n"),
+ r, r2, KErrNone, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ gTestThread.Close();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test4: Call general defrag and zone defrag at the same time "));
+ TestStart();
+
+ TInt waitTime = 10000;
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && gZoneUtilArray[index].iAllocFixed > 0)
+ {
+ index--;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && gZoneUtilArray[index].iAllocFixed > 0)
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = gTestThread.Create(gTestThreadName,MultiGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+
+ gTestThread.Resume();
+ User::After(waitTime);
+
+ TESTDEBUG(test.Printf(_L("Zone defrag running on main thread\n")));
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, defragZoneID);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (r2 != KErrNone ||
+ (freeInOthers && (r != KErrNone || !CheckZoneIsOff(index))))
+ {
+ test.Printf(_L("Fail: r = %d, r2 = %d, expected = %d, or zone %d is on unexpectedly\n"),
+ r, r2, KErrNone, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ gTestThread.Close();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test5: Call zone defrag and general defrag at the same time "));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = gTestThread.Create(gTestThreadName,MultiEmptyZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny*)defragZoneID);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+
+ gTestThread.Resume();
+ User::After(0);
+
+ TESTDEBUG(test.Printf(_L("Zone defrag running on main thread\n")));
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, gDefragMaxPages);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (r != KErrNone ||
+ (freeInOthers && (r2 != KErrNone || !CheckZoneIsOff(index))))
+ {
+ test.Printf(_L("Fail: r = %d, r2 = %d, expected = %d, or zone 0x%x is on unexpectedly\n"),
+ r, r2, KErrNone, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ gTestThread.Close();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test6: Call function TRamDefragRequest::EmptyRamZone on specifc zone and at the same time allocate pages to the zone"));
+ TestStart();
+
+ TInt pagesAlloc = 1; // Try and allocate just one page whilst trying to empty the zone.
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TInt numPassed = 0;
+ for (waitTime = 1000; waitTime > 0; waitTime-=10)
+ {
+ r = gTestThread.Create(gTestThreadName,MultiEmptyZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny*)defragZoneID);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ gTestThread.Logon(status);
+
+ gTestThread.Resume();
+ User::After(waitTime);
+
+ r = Ldd.ZoneAllocDiscontiguous(defragZoneID, pagesAlloc);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ if (r2 != KErrNone)
+ {
+ test.Printf(_L("Empty was unsuccsessful: r2 = %d, expected = %d\n"), r2, KErrNone);
+ }
+ else if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d, r2 = %d, expected = %d, zone = 0x%x\n"),
+ r, KErrNone, r2, KErrNone, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ numPassed ++;
+ }
+
+ Ldd.FreeAllFixedPages();
+
+ gTestThread.Close();
+ }
+ if (numPassed > 0)
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test7: Call function TRamDefragRequest::EmptyRamZone on every zone one after the other"));
+ TestStart();
+
+ Ldd.ResetDriver();
+
+ for (index = 0; index < gZoneCount; index ++)
+ {
+ // Variables for DP ROM cache sizes
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ if (gPagedRom)
+ {
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ // Calculate the maximum size available for the DP cache.
+ TUint minZoneFree = KMaxTUint;
+ TUint maxDisFillBytes = 0;
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ maxDisFillBytes += gZoneUtilArray[i].iFreePages;
+ maxDisFillBytes += gZoneUtilArray[i].iAllocDiscardable;
+ if (minZoneFree > gZoneUtilArray[i].iFreePages)
+ minZoneFree = gZoneUtilArray[i].iFreePages;
+ }
+ test.Printf(_L("Free pages 0x%x maxDisFillBytes 0x%x\n"), gTotalPageCount.iFreePages, maxDisFillBytes);
+ maxDisFillBytes <<= gPageShift;
+
+ r = DPTest::SetCacheSize(maxDisFillBytes, maxDisFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("CacheSize2: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ if (currentCacheSize != maxDisFillBytes)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ GetAllPageInfo();
+ test.Printf(_L("Free pages after alloc discardable1 = 0x%x\n"), gTotalPageCount.iFreePages);
+
+ r = DPTest::SetCacheSize(minZoneFree << gPageShift, maxDisFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ // Check all zones have no free pages.
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gZoneUtilArray[i].iFreePages != 0)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ }
+ else
+ {
+ // Fragment the RAM with some movable pages
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+ }
+
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+
+ GetAllPageInfo();
+ TUint origUnknownInZone = gZoneUtilArray[index].iAllocUnknown;
+ TUint origMovInZone = gZoneUtilArray[index].iAllocMovable;
+ TUint origFreeInZone = gZoneUtilArray[index].iFreePages;
+
+ test.Printf(_L("Zone ID 0x%x - fixedPages = 0x%x, unknownPages = 0x%x, discardablePages = 0x%x movable = 0x%x free = 0x%x\n"),
+ zoneID, gZoneUtilArray[index].iAllocFixed, origUnknownInZone, gZoneUtilArray[index].iAllocDiscardable,
+ origMovInZone, origFreeInZone);
+
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, zoneID);
+
+ GetAllPageInfo();
+ TUint unknownPages = gZoneUtilArray[index].iAllocUnknown;
+ TUint discPages = gZoneUtilArray[index].iAllocDiscardable;
+ TUint movablePages = gZoneUtilArray[index].iAllocMovable;
+
+ TUint freeInOtherZones = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if(movablePages && freeInOtherZones)
+ {
+ test.Printf(_L("Fail: Zone ID %x all the movable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ if (origUnknownInZone != unknownPages)
+ {
+ test.Printf(_L("Fail: Zone ID %x unknown pages before and after are not equal\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ if (!gPagedRom)
+ {
+ if (discPages && freeInOtherZones)
+ {
+ test.Printf(_L("Fail: Zone ID %x all the discardable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ else
+ {
+ DPTest::CacheSize(minCacheSize, maxCacheSize, currentCacheSize);
+ TESTDEBUG(test.Printf(_L("CacheSize3: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ // The the discardable pages should have been discarded or moved unless
+ // there is no room in the other zones and the cache size is already at its minimum
+ if (discPages && (freeInOtherZones || currentCacheSize != minCacheSize))
+ {
+ test.Printf(_L("Fail: Zone 0x%x all the discardable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ test.Printf(_L("Passed...\n"));
+ }
+ // TestEnd() willl cleanup what's required
+ TestEnd();
+
+ test.Next(_L("Test8: Call function TRamDefragRequest::EmptyRamZone on a zone that contains fixed and movable pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocMovable < 10 || gZoneUtilArray[index].iFreePages < 3))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocMovable < 10 || gZoneUtilArray[index].iFreePages < 3))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ test.Printf(_L("defragZoneID = 0x%x\n"), defragZoneID);
+ test.Printf(_L("movable = 0x%x discardable = 0x%x\n"),
+ gZoneUtilArray[index].iAllocMovable, gZoneUtilArray[index].iAllocDiscardable);
+
+
+ Ldd.ZoneAllocDiscontiguous(defragZoneID, 2); // Allocated 2 fixed pages to ensure that zone cannot be emptied
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, defragZoneID);
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (r != KErrNoMemory ||
+ (freeInOthers &&
+ (gZoneUtilArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocDiscardable)))
+ {
+ test.Printf(_L("r = %d, expected = %d, or all movable/discardable pages have not been moved"),
+ r, KErrNoMemory);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+
+ Ldd.FreeAllFixedPages();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.End();
+ return r;
+ }
+
+
+//
+// TestClaimRamZone
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0532
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the implemntation of the function TRamDefragRequest::ClaimRamZone()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this, call function with a valid aID
+//! 2. Fragment the memory. Following this, call function with an invalid aID
+//! 3. Fragment the memory. Following this, start a zone defrag and whilst this
+//! is running, call function on the same zone.
+//! 4. Fragment the memory. Following this, start a general defrag and whilst this
+//! is running, call function on the same zone.
+//! 5. Fragment the memory. Following this, call ClaimRamZone() on a specific zone, whilst at the
+//! same time calling ClaimRamZone() on another zone.
+//! 6: Fragment the memory. Call function TRamDefragRequest::ClaimRamZone on specifc zone and at the
+//! same time allocate pages to the zone
+//! 7. Fragment the memory. Following this allocate fixed pages to a zone and attempt to claim
+//! the zone.
+//! 8. Fragment the memory. Following this call ClaimRamZone() on every zone, one after the other
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//! 2. KErrArgument
+//! 3. KErrNone and the zone has been claimed
+//! 4. KErrNone and the zone has been claimed
+//! 5. KErrNone and both zones have been claimed
+//! 6. KErrNoMemory
+//! 7. KErrNoMemory, all movable and discardable pages have been moved
+//! 8. One of the following scenarios should occur:
+//! a. If the cache has not reached its minimum size and there are no unknown pages in
+//! the zone, then all the movable pages should be moved from the zone if there are enough free pages
+//! in the other zones.
+//! However, when demand paging is off, all movable pages should be moved from the zone, again if there
+//! are enough free pages in the other zones and if there are no unknown pages in the zone.
+//! b. If the current size of the cache minus the number of discardable pages in the zone being emptied is not
+//! less than the minimum cache size and there are no unknown pages in the zone,
+//! then all the discardable pages should be discarded of.
+//! However, when demand paging is off, all discardable pages should be removed from
+//! the zone if there are no unknown pages in the zone.
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestClaimRamZone()
+ {
+ TInt r = 0;
+ TInt r2 = 0;
+ TUint32 addr = 0;
+ TInt waitTime = 1000;
+
+ test.Start(_L("Test1: Call function TRamDefragRequest::ClaimRamZone with a valid aID"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ TUint defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r != KErrNone &&
+ gZoneUtilArray[index].iAllocFixed != gZoneUtilArray[index].iPhysPages)
+ {
+ test.Printf(_L("Fail: Zone 0x%x has not been claimed r %d expected %d\n"), defragZoneID, r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ addr = gZoneConfigArray[index].iPhysBase;
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeAllFixedPages();
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call function TRamDefragRequest::ClaimRamZone with an invalid aID"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ defragZoneID = KInvalidZoneID;
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call function TRamDefragRequest::ClaimRamZone when a EmptyRamZone is already running"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TInt numPassed = 0;
+ for (waitTime = 1000; waitTime > 0; waitTime-=10)
+ {
+ r = gTestThread.Create(gTestThreadName,MultiEmptyZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny*)defragZoneID);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+ User::After(waitTime);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r != KErrNone && r2 != KErrNone)
+ {
+ test.Printf(_L("Fail: r = %d, r2 = %d, expected = %d, or zone ID 0x%x has not been claimed\n"),
+ r, r2, KErrNone, defragZoneID);
+ if (r == KErrNone)
+ {
+ CLEANUP(r = Ldd.FreeAllFixedPages());
+ }
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ numPassed ++;
+ }
+
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeAllFixedPages();
+ }
+
+ gTestThread.Close();
+ }
+ if (numPassed > 0)
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test4: Call function TRamDefragRequest::ClaimRamZone when a general defrag is already running"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ r = gTestThread.Create(gTestThreadName,MultiGenDefragThreadFunc,KDefaultStackSize,0x1000,0x1000,NULL);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+ User::After(waitTime);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ if (r != KErrNone)
+ {
+ test.Printf(_L("ClaimZone: r = %d, expected = %d\n"), r, KErrNone);
+ }
+
+ if (r2 != KErrNone)
+ {
+ test.Printf(_L("General: r2 = %d, expected = %d\n"), r, KErrNone);
+ }
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && gZoneUtilArray[index].iAllocFixed != gZoneUtilArray[index].iPhysPages)
+ {
+ test.Printf(_L("Fail: Zone ID 0x%x has not been claimed, r = %d, r2 = %d, expected = %d\n"),
+ defragZoneID, r, r2, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeAllFixedPages();
+ }
+
+ gTestThread.Close();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+
+ test.Next(_L("Test5: Call function TRamDefragRequest::ClaimRamZone on specifc zone at the same time as calling on another zone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+ test.Printf(_L("index = 0x%x "), index);
+
+ TUint index2 = gZoneCount - 1;
+ while ( index2 > 0 &&
+ (index == index2 || gZoneUtilArray[index2].iAllocFixed != 0 || gZoneUtilArray[index2].iAllocUnknown != 0))
+ {
+ -- index2;
+ }
+ TUint defragZoneID2 = gZoneConfigArray[index2].iZoneId;
+ test.Printf(_L("index2 = %d\n"), index2);
+
+ if ((index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0)) ||
+ (index2 == 0 && (index == index2 || gZoneUtilArray[index2].iAllocFixed != 0 || gZoneUtilArray[index2].iAllocUnknown != 0)))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = gTestThread.Create(gTestThreadName,MultiClaimZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny*)(defragZoneID2));
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+ User::After(waitTime);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ TUint freeInOthers2 = gTotalPageCount.iFreePages - gZoneUtilArray[index2].iFreePages;
+ if ((freeInOthers && r != KErrNone &&
+ gZoneUtilArray[index].iAllocFixed != gZoneUtilArray[index].iPhysPages) ||
+ (freeInOthers2 && r != KErrNone &&
+ gZoneUtilArray[index2].iAllocFixed != gZoneUtilArray[index2].iPhysPages))
+ {
+ test.Printf(_L("Fail: Zone ID 0x%x or Zone ID 0x%x has not been claimed, r = %d, r2 = %d, expected = %d\n"),
+ defragZoneID, defragZoneID2, r, r2, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeAllFixedPages();
+ }
+
+ if (r2 == KErrNone)
+ {// Have to free from specific address as RAM zone claimed by other channel.
+ addr = gZoneConfigArray[index2].iPhysBase;
+ r = Ldd.FreeFromAddr(gZoneUtilArray[index2].iAllocFixed, addr);
+ }
+
+ gTestThread.Close();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test6: Call function TRamDefragRequest::ClaimRamZone on specifc zone and at the same time allocate pages to the zone"));
+ TestStart();
+
+ TInt pagesAlloc = 1; // Try and allocate just one page whilst attempting to claim the zone
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ GetAllPageInfo();
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+ TInt numPassed = 0;
+ for (waitTime = 1000; waitTime > 0; waitTime-=10)
+ {
+ r = gTestThread.Create(gTestThreadName,MultiClaimZoneThreadFunc,KDefaultStackSize,0x1000,0x1000,(TAny*)defragZoneID);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+
+ gTestThread.Logon(status);
+ gTestThread.Resume();
+ test(status.Int() == KRequestPending);
+ User::After(waitTime);
+
+ r = Ldd.ZoneAllocDiscontiguous(defragZoneID, pagesAlloc);
+
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+
+ User::WaitForRequest(status);
+ r2 = status.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r2 != KErrNone)
+ {
+ test.Printf(_L("Claim was unsuccsessful: r2 = %d, expected = %d\n"), r2, KErrNone);
+ }
+ else if (r2 == KErrNone && r != KErrNoMemory)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d, r2 = %d, expected = %d, zone ID = 0x%x\n"),
+ r, KErrNoMemory, r2, KErrNone, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ // Free from address as a different channel claimed the RAM zone.
+ addr = gZoneConfigArray[index].iPhysBase;
+ CLEANUP(Ldd.FreeFromAddr(gZoneUtilArray[index].iAllocFixed, addr));
+ TEST_FAIL;
+ }
+ else
+ {
+ numPassed ++;
+ }
+
+ Ldd.FreeAllFixedPages();
+
+ GetAllPageInfo();
+ if (r2 == KErrNone)
+ {// Free from address as a different channel claimed the RAM zone.
+ addr = gZoneConfigArray[index].iPhysBase;
+ r = Ldd.FreeFromAddr(gZoneUtilArray[index].iAllocFixed, addr);
+ }
+ gTestThread.Close();
+ }
+ if (numPassed > 0)
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+
+ test.Next(_L("Test7: Call function TRamDefragRequest::ClaimRamZone on a zone that contains fixed and movable pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0) &&
+ (gZoneUtilArray[index].iAllocMovable < 10 || gZoneUtilArray[index].iFreePages < 3))
+ {
+ -- index;
+ }
+
+ if (index == 0 && ((gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0) &&
+ (gZoneUtilArray[index].iAllocMovable < 10 || gZoneUtilArray[index].iFreePages < 3)))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+ TESTDEBUG(test.Printf(_L("defragZoneID = 0x%x\n"), defragZoneID));
+ TESTDEBUG(test.Printf(_L("movable = 0x%x discardable = 0x%x\n"),
+ gZoneUtilArray[index].iAllocMovable, gZoneUtilArray[index].iAllocDiscardable));
+
+
+ Ldd.ZoneAllocDiscontiguous(defragZoneID, 2); // Allocated 2 fixed pages to ensure that zone cannot be emptied
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, defragZoneID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (r != KErrNoMemory ||
+ (freeInOthers &&
+ (gZoneUtilArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocDiscardable)))
+ {
+ test.Printf(_L("r = %d, expected = %d, or all movable/discardable pages have not been moved"),
+ r, KErrNoMemory);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ Ldd.FreeAllFixedPages();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.Next(_L("Test8: Call function TRamDefragRequest::ClaimRamZone on every zone one after the other"));
+ TestStart();
+
+ Ldd.ResetDriver();
+
+ for (index = 0; index < gZoneCount; index ++)
+ {
+ // Variables for DP ROM cache sizes
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ if (gPagedRom)
+ {
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ // Calculate the maximum size of the DP cache
+ TUint minZoneFree = KMaxTUint;
+ TUint maxDisFillBytes = 0;
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ maxDisFillBytes += gZoneUtilArray[i].iFreePages;
+ maxDisFillBytes += gZoneUtilArray[i].iAllocDiscardable;
+ if (minZoneFree > gZoneUtilArray[i].iFreePages)
+ minZoneFree = gZoneUtilArray[i].iFreePages;
+ }
+ test.Printf(_L("Free pages 0x%x maxDisFillBytes 0x%x\n"), gTotalPageCount.iFreePages, maxDisFillBytes);
+ maxDisFillBytes <<= gPageShift;
+
+ r = DPTest::SetCacheSize(maxDisFillBytes, maxDisFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("CacheSize2: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ if (currentCacheSize != maxDisFillBytes)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ GetAllPageInfo();
+ test.Printf(_L("Free pages after alloc discardable1 = 0x%x\n"), gTotalPageCount.iFreePages);
+
+ r = DPTest::SetCacheSize(minZoneFree << gPageShift, maxDisFillBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ // Check all zones have no free pages.
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gZoneUtilArray[i].iFreePages != 0)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ }
+ else
+ {
+ // Fragment the RAM with some movable pages
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+ }
+
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+
+ GetAllPageInfo();
+ TUint origUnknownInZone = gZoneUtilArray[index].iAllocUnknown;
+ TUint origMovInZone = gZoneUtilArray[index].iAllocMovable;
+ TUint origFreeInZone = gZoneUtilArray[index].iFreePages;
+
+ test.Printf(_L("Zone ID 0x%x - fixedPages = 0x%x, unknownPages = 0x%x, discardablePages = 0x%x movable = 0x%x free = 0x%x\n"),
+ zoneID, gZoneUtilArray[index].iAllocFixed, origUnknownInZone, gZoneUtilArray[index].iAllocDiscardable,
+ origMovInZone, origFreeInZone);
+
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, zoneID);
+
+ GetAllPageInfo();
+ TUint unknownPages = gZoneUtilArray[index].iAllocUnknown;
+ TUint discPages = gZoneUtilArray[index].iAllocDiscardable;
+ TUint movablePages = gZoneUtilArray[index].iAllocMovable;
+
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeAllFixedPages();
+ }
+ TUint freeInOtherZones = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (!unknownPages && movablePages && freeInOtherZones)
+ {
+ test.Printf(_L("Fail: Zone ID %x all the movable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ if (origUnknownInZone != unknownPages)
+ {
+ test.Printf(_L("Fail: Zone ID %x unknown pages before and after are not equal\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ if (!gPagedRom)
+ {
+ if (!unknownPages && freeInOtherZones && discPages)
+ {
+ test.Printf(_L("Fail: Zone ID %x all the discardable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ else
+ {
+ DPTest::CacheSize(minCacheSize, maxCacheSize, currentCacheSize);
+ TESTDEBUG(test.Printf(_L("CacheSize3: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ // The the discardable pages should have been discarded or moved unless
+ // there is no room in the other zones and the cache size is already at its minimum
+ if (!unknownPages && discPages && (freeInOtherZones || currentCacheSize != minCacheSize))
+ {
+ test.Printf(_L("Fail: Zone ID 0x%x all the discardable pages haven't been moved\n"), zoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+ test.Printf(_L("Passed...\n"));
+ }
+ // TestEnd() will cleanup what's required.
+ TestEnd();
+ test.End();
+ return 0;
+ }
+
+
+//
+// TestCancelDefrag
+//
+//-----------------------------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0533
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the implementation of the function TRamDefragRequest::CancelDefrag()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this, start a general defrag and cancel it
+//! 2. Fragment the memory. Following this, start a zone defrag and cancel it
+//! 3. Fragment the memory. Following this, start a claim zone and cancel it
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrCancel
+//! 2. KErrCancel
+//! 3. KErrCancel
+//-----------------------------------------------------------------------------------------------------------------------------------------
+TInt TestCancelDefrag()
+ {
+ TInt r = 0;
+ TUint defragZoneID = 0;
+
+ test.Start(_L("Test1: Call general defrag and cancel it"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ r = Ldd.CheckCancel(DEFRAG_TYPE_GEN);
+
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r != KErrCancel)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrCancel);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call zone defrag and cancel it"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 &&
+ (gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages ||
+ gZoneUtilArray[index].iAllocFixed !=0 ||
+ gZoneUtilArray[index].iAllocUnknown !=0))
+ {
+ -- index;
+ }
+ if (index == 0 &&
+ (gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages ||
+ gZoneUtilArray[index].iAllocFixed !=0 ||
+ gZoneUtilArray[index].iAllocUnknown !=0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+ TESTDEBUG(test.Printf(_L("defragZoneID = 0x%x\n"),defragZoneID));
+
+ r = Ldd.CheckCancel(DEFRAG_TYPE_EMPTY, defragZoneID);
+
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r != KErrCancel)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrCancel);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call Claim RAM Zone and cancel it"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 &&
+ (gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages ||
+ gZoneUtilArray[index].iAllocFixed !=0 ||
+ gZoneUtilArray[index].iAllocUnknown !=0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+ TESTDEBUG(test.Printf(_L("defragZoneID = 0x%x\n"),defragZoneID));
+
+ if (index == 0 &&
+ (gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages ||
+ gZoneUtilArray[index].iAllocFixed !=0 ||
+ gZoneUtilArray[index].iAllocUnknown !=0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CheckCancel(DEFRAG_TYPE_CLAIM, defragZoneID);
+
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r != KErrCancel)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrCancel);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.End();
+ return 0;
+ }
+
+//
+// TestZoneAllocNoAffect
+//
+// Ensures that fixed page allocations do not affect the movable
+// or discardable page allocations
+//
+TInt TestZoneAllocNoAffect(TInt aZoneAllocType, TInt aPageType)
+ {
+ TInt retVal = KErrNone;
+ TInt r = KErrNone;
+ TInt mostPrefIndex = 0;
+ TUint leastPrefIndex = 0;
+ TUint leastPrefZoneID = 0;
+
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ switch(aPageType)
+ {
+ case BEST_MOVABLE:
+ test.Printf(_L("Test Epoc::ZoneAllocPhysicalRam() doesn't affect the allocation of movable pages\n"));
+ break;
+
+ case BEST_DISCARDABLE:
+ test.Printf(_L("Test Epoc::ZoneAllocPhysicalRam() doesn't affect the allocation of discardable pages\n"));
+ if (!gPagedRom)
+ {
+ test.Printf(_L("Not a paged ROM - Skipping...\n"));
+ goto skipSetup;
+ }
+ break;
+ }
+ // Fist find the zone that movable page allocations should go into
+ // Getting the best movable will be the same for discardable as well
+ mostPrefIndex = GetBestZone(aPageType);
+ if (mostPrefIndex == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ goto skipSetup;
+ }
+
+ // Get the least pref zone to zone alloc into and ensure it has free pages
+ GetPrefOrder();
+ leastPrefIndex = gPrefArray[gZoneCount - 1];
+ if (gZoneConfigArray[mostPrefIndex].iPref == gZoneConfigArray[leastPrefIndex].iPref)
+ {
+ test.Printf(_L("Zones with same preference - Skipping...\n"));
+ goto skipSetup;
+ }
+ if (leastPrefIndex == (TUint)mostPrefIndex ||
+ gZoneUtilArray[leastPrefIndex].iFreePages == 0)
+ {
+ test.Printf(_L("leastPrefIndex = mostPrefIndex or leastPrefIndex(%d) / mostPrefIndex(%d) has 0 free - Skipping test step...\n"),
+ leastPrefIndex, mostPrefIndex);
+ goto skipSetup;
+ }
+
+
+ // Zone alloc 1 fixed page into the least preferable zone
+ leastPrefZoneID = gZoneConfigArray[leastPrefIndex].iZoneId;
+ GetOriginalPageCount();
+ switch(aZoneAllocType)
+ {
+ case Z_ALLOC_DISC:
+ {
+ r = Ldd.ZoneAllocDiscontiguous(leastPrefZoneID, 1);
+ break;
+ }
+
+ case Z_ALLOC_CONTIG:
+ {
+ r = Ldd.ZoneAllocContiguous(leastPrefZoneID, gPageSize);
+ break;
+ }
+ }
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[leastPrefIndex].iAllocFixed <= gOriginalPageCountArray[leastPrefIndex].iAllocFixed)
+ {
+ test.Printf(_L("Failed to allocate 1 fixed page to zone index %d r = %d\n"), leastPrefIndex, r);
+ goto skipSetup;
+ }
+ test.Printf(_L("leastPrefIndex = %d mostPrefIndex = %d\n"), leastPrefIndex, mostPrefIndex);
+ switch(aPageType)
+ {
+ case BEST_MOVABLE:
+ // now allocate 1 movable page
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, 1, gPageSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 movable page r = %d\n"), r);
+ goto skipSetup;
+ }
+ break;
+
+ case BEST_DISCARDABLE:
+ // now allocate 1 discardable page
+ TInt disPages;
+ TUint disBytes = (gTotalPageCount.iDiscardablePages + 1) << gPageShift;
+ r = AllocDiscardable(disPages, disBytes);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate 1 discardable page r = %d\n"), r);
+ goto skipSetup;
+ }
+ break;
+ }
+
+ GetAllPageInfo();
+ switch(aPageType)
+ {
+ case BEST_MOVABLE:
+ if (gOriginalPageCountArray[mostPrefIndex].iAllocMovable >= gZoneUtilArray[mostPrefIndex].iAllocMovable ||
+ gOriginalPageCountArray[leastPrefIndex].iAllocMovable < gZoneUtilArray[leastPrefIndex].iAllocMovable)
+ {
+ test.Printf(_L("FAIL: mostPrefIndex(%d) origMov 0x%x curMov 0x%x leastPrefIndex(%d) origMov 0x%x curMov 0x%x\n"),
+ mostPrefIndex, gOriginalPageCountArray[mostPrefIndex].iAllocMovable, gZoneUtilArray[mostPrefIndex].iAllocMovable,
+ leastPrefIndex, gOriginalPageCountArray[leastPrefIndex].iAllocMovable, gZoneUtilArray[leastPrefIndex].iAllocMovable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ retVal = KErrGeneral;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ break;
+
+
+ case BEST_DISCARDABLE:
+ if (gOriginalPageCountArray[mostPrefIndex].iAllocDiscardable >= gZoneUtilArray[mostPrefIndex].iAllocDiscardable ||
+ gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable < gZoneUtilArray[leastPrefIndex].iAllocDiscardable)
+ {
+ test.Printf(_L("FAIL: mostPrefIndex(%d) origDis 0x%x curDis 0x%x leastPrefIndex(%d) origDis 0x%x curDis 0x%x\n"),
+ mostPrefIndex, gOriginalPageCountArray[mostPrefIndex].iAllocDiscardable, gZoneUtilArray[mostPrefIndex].iAllocDiscardable,
+ leastPrefIndex, gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable, gZoneUtilArray[leastPrefIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ retVal = KErrGeneral;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ break;
+ }
+
+ // This will clean up any fixed pages allocated.
+skipSetup:
+ TestEnd();
+ return retVal;
+ }
+
+//
+// TestZoneAllocContiguous
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0535
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the contiguous overload of Epoc::ZoneAllocPhysicalRam().
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Call function with a valid aZoneID.
+//! 2. Call function with an invalid aZoneID
+//! 3. Call function with aSize > zone size
+//! 4. Call multiple RAM zone overload of the function with a mix of valid and invalid IDs.
+//! 5. Call multiple RAM zone overload of the function with contiguous RAM zones and attempt
+//! to allocate over both RAM zones.
+//! 6. Call function on a RAM zone that has some non-DP pages allocated into it and ask
+//! for the whole RAM zone to be filled with fixed pages.
+//! 7. Get the most preferable zone for movable page allocations (mostPref). Allocate 1 contiguous fixed page
+//! in the least preferable zone. Following this allocate 1 movable page
+//! 8. Get the most preferable zone for discardable page allocations (mostPref). Allocate 1 contiguous fixed
+//! page in the least preferable zone. Following this allocate 1 discardable page
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//! 2. KErrArgument
+//! 3. KErrArgument
+//! 4. KErrArgument
+//! 5. KErrNone
+//! 6. KErrNoMemory
+//! 7. Movable pages are allocated into zone mostPref.
+//! 8. Discardable pages are allocated into zone mostPref
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestZoneAllocContiguous()
+ {
+ TInt r = 0;
+ test.Start(_L("Test1: Call function Epoc::ZoneAllocPhysicalRam() with a valid aZoneID"));
+ TestStart();
+
+ const TUint KAllocPages = 2;
+
+ GetOriginalPageCount();
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 && gZoneUtilArray[index].iFreePages < KAllocPages)
+ {
+ -- index;
+ }
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ if (index == 0 && gZoneUtilArray[index].iFreePages < KAllocPages)
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TUint allocBytes = KAllocPages << gPageShift;
+ r = Ldd.ZoneAllocContiguous(zoneID, allocBytes);
+ GetAllPageInfo();
+ if (r == KErrNone &&
+ gZoneUtilArray[index].iAllocFixed - gOriginalPageCountArray[index].iAllocFixed == KAllocPages)
+ {
+ test.Printf(_L("Pass: Correct number of fixed pages allocated to zone ID 0x%x\n"),zoneID);
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d, or number of pages allocated is not expected\n"),
+ r, KErrNone);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+
+ Ldd.FreeAllFixedPages();
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call function Epoc::ZoneAllocPhysicalRam() with an invalid aZoneID"));
+ TestStart();
+
+ zoneID = KInvalidZoneID;
+
+ TESTDEBUG(test.Printf(_L("zoneID = 0x%x\n"), zoneID));
+
+ r = Ldd.ZoneAllocContiguous(zoneID, gPageSize);
+ GetAllPageInfo();
+ if (r == KErrArgument)
+ {
+ test.Printf(_L("Pass: Correct return value\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ Ldd.FreeAllFixedPages();
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call function Epoc::ZoneAllocPhysicalRam() with aSize > zone size"));
+ TestStart();
+
+ index = gZoneCount - 1;
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ TUint allocBytes = (gZoneUtilArray[index].iPhysPages + 5) << gPageShift;
+
+ r = Ldd.ZoneAllocContiguous(zoneID, allocBytes);
+ GetAllPageInfo();
+ if (r == KErrArgument)
+ {
+ test.Printf(_L("Pass: Correct return value and number of pages allocated is correct\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ Ldd.FreeAllFixedPages();
+ TestEnd();
+
+ const TUint KMultiZoneIds = 10;
+ TUint* zoneIdArray = new TUint[KMultiZoneIds];
+ test_NotNull(zoneIdArray);
+
+ test.Next(_L("Test4: Test Epoc::ZoneAllocPhysicaRam() always fails when at least one ID is invalid"));
+ TestStart();
+
+ index = gZoneCount - 1;
+ while (index > 0 && gZoneUtilArray[index].iFreePages < KAllocPages)
+ {
+ -- index;
+ }
+ if (index == 0 && gZoneUtilArray[index].iFreePages < KAllocPages)
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TUint zoneIdSize = 2;
+ zoneIdArray[0] = gZoneConfigArray[index].iZoneId;
+ zoneIdArray[1] = KInvalidZoneID;
+ TUint allocBytes = KAllocPages << gPageShift;
+ r = Ldd.MultiZoneAllocContiguous(zoneIdArray, zoneIdSize, allocBytes);
+ if (r != KErrArgument)
+ {
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Pass: Correct return value\n"));
+ }
+ }
+
+ TestEnd();
+
+ test.Next(_L("Test5: Test Epoc::ZoneAllocPhysicalRam() can span multiple RAM zones"));
+ TestStart();
+ // Attempt to find to physically contiguous RAM zones where higher addressed
+ // one is empty, relies on RAM zones are returned by HAL functions in
+ // ascending physical address order.
+ GetAllPageInfo();
+ TBool zonesFound = EFalse;
+ index = gZoneCount - 1;
+ for (; index > 1; index--)
+ {
+ if (gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages &&
+ gZoneUtilArray[index-1].iFreePages == gZoneUtilArray[index-1].iPhysPages &&
+ gZoneConfigArray[index].iPhysBase - 1 == gZoneConfigArray[index-1].iPhysEnd)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Allocate one page more than the first RAM zone to force the allocation
+ // to spread over both RAM zones.
+ TUint allocPages = gZoneUtilArray[index-1].iPhysPages + 1;
+ TUint allocBytes = allocPages << gPageShift;
+
+ // Attempt to find a zone that has less free pages than the allocation
+ // size so we can test that the method continues past too full RAM zones.
+ zonesFound = EFalse;
+ TUint noAllocZone = 0;
+ for (; noAllocZone < gZoneCount; noAllocZone++)
+ {
+ if (allocPages > gZoneUtilArray[noAllocZone].iFreePages &&
+ noAllocZone != index && noAllocZone != index-1)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ TUint zoneIds = 2;
+ if (!zonesFound)
+ {
+ zoneIdArray[0] = gZoneConfigArray[index-1].iZoneId;
+ zoneIdArray[1] = gZoneConfigArray[index].iZoneId;
+ }
+ else
+ {// Have a zone that won't meet the allocation so use it
+ TESTDEBUG(test.Printf(_L("noAllocZone ID %x\n"), gZoneConfigArray[noAllocZone].iZoneId));
+ zoneIds++;
+ zoneIdArray[0] = gZoneConfigArray[noAllocZone].iZoneId;
+ zoneIdArray[1] = gZoneConfigArray[index-1].iZoneId;
+ zoneIdArray[2] = gZoneConfigArray[index].iZoneId;
+ }
+
+ r = Ldd.MultiZoneAllocContiguous(zoneIdArray, zoneIds, allocBytes);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[index].iFreePages == gZoneUtilArray[index].iPhysPages ||
+ gZoneUtilArray[index-1].iFreePages == gZoneUtilArray[index-1].iPhysPages)
+ {// The allocation failed.
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ // TestEnd() will free the allocation of fixed pages.
+ TestEnd();
+
+ test.Next(_L("Test6: Test Epoc::ZoneAllocPhysicalRam() returns KErrNoMemory when appropriate"));
+ TestStart();
+ // Attempt to find a RAM zone with some non-discarable pages allocated into it.
+ // (At time of writing discardable pages wouldn't be discarded on demand by
+ // this function but this may be changed in the future as discontiguous case does that).
+ GetAllPageInfo();
+ zonesFound = EFalse;
+ index = gZoneCount - 1;
+ for (; index > 0; index--)
+ {
+ if (gZoneUtilArray[index].iFreePages &&
+ (gZoneUtilArray[index].iAllocMovable || gZoneUtilArray[index].iAllocFixed))
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Attempt to allocate the whole of the RAM zone.
+ GetOriginalPageCount();
+ TUint allocBytes = gZoneConfigArray[index].iPhysPages << gPageShift;
+ r = Ldd.ZoneAllocContiguous(gZoneConfigArray[index].iZoneId, allocBytes);
+
+ // The allocation should have failed and no pages should have
+ // been allocated.
+ GetAllPageInfo();
+ if (r != KErrNoMemory ||
+ gOriginalPageCountArray[index].iFreePages > gZoneUtilArray[index].iFreePages)
+ {
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Pass: Correct return value\n"));
+ }
+ }
+ // TestEnd() will free the allocation of fixed pages.
+ TestEnd();
+ delete[] zoneIdArray;
+
+
+ test.Next(_L("Test7: Test Epoc::ZoneAllocPhysicalRam() (Contiguous) doesn't affect the allocation of movable pages"));
+ r = TestZoneAllocNoAffect(Z_ALLOC_CONTIG, BEST_MOVABLE);
+ if (r != KErrNone)
+ {
+ TEST_FAIL;
+ }
+
+ test.Next(_L("Test8: Test Epoc::ZoneAllocPhysicalRam() (Contiguous) doesn't affect the allocation of discardable pages"));
+ r = TestZoneAllocNoAffect(Z_ALLOC_CONTIG, BEST_DISCARDABLE);
+ if (r != KErrNone)
+ {
+ TEST_FAIL;
+ }
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestZoneAllocDiscontiguous
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0536
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the discontiguous overload of Epoc::ZoneAllocPhysicalRam().
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Call function with a valid aZoneID.
+//! 2. Call function with an invalid aZoneID
+//! 3. Call function with aNumPages > zone size
+//! 4. Call multiple RAM zone overload of function with a mix of valid and invalid IDs
+//! 5. Call multiple RAM zone overload of function so that the allocation will have to
+//! span multiple RAM zones.
+//! 6. Call function with memory full with DP cache that has reached it's
+//! minimum cache size.
+//! 7. Call function with memory not quite full with DP cache that has reached it's
+//! minimum cache size and with the specified RAM zone full.
+//! 8. Call function to allocate a whole RAM zone on a RAM zone that has non-discardable
+//! pages already allocated into it.
+//! 9. Call function to allocate one less than the whole RAM zone on a RAM zone that has movable
+//! pages allocated.
+//! 10. Get the most preferable zone for movable page allocations (mostPref). Allocate 1 discontiguous fixed page
+//! in the least preferable zone. Following this allocate 1 movable page
+//! 11. Get the most preferable zone for discardable page allocations (mostPref). Allocate 1 discontiguous fixed
+//! page in the least preferable zone. Following this allocate 1 discardable page
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//! 2. KErrArgument
+//! 3. KErrArgument
+//! 4. KErrArgument
+//! 5. KErrNone
+//! 6. KErrNoMemory
+//! 7. KErrNone
+//! 8. KErrNoMemory
+//! 9. KErrNone (i.e. the movable pages are shifted out of the way but only those that need to be moved).
+//! 10. Movable pages are allocated into zone mostPref.
+//! 11. Discardable pages are allocated into zone mostPref
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestZoneAllocDiscontiguous()
+ {
+ TInt r = KErrNone;
+ test.Start(_L("Test1: Call function Epoc::ZoneAllocPhysicalRam() with a valid aZoneID"));
+ TestStart();
+
+ const TUint KAllocPages = 5;
+ // Detemine how many extra pages the kernel heap may grow by
+ // as these may need to be accounted for.
+ TUint fixedOverhead = Ldd.GetAllocDiff(KAllocPages);
+
+ GetOriginalPageCount();
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 && gZoneUtilArray[index].iFreePages < KAllocPages)
+ {
+ -- index;
+ }
+
+ if (gZoneUtilArray[index].iFreePages < KAllocPages || gTotalPageCount.iFreePages < KAllocPages + fixedOverhead)
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Allocate KAllocPages discontiguous fixed pages into RAM zone zoneID
+ // and verfiy that the pages were allocated to the correct zone, allow for
+ // extra fixed pages to be allocated as the kernel heap may grow.
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, KAllocPages);
+
+ GetAllPageInfo();
+ if ((r == KErrNone) &&
+ (gZoneUtilArray[index].iAllocFixed >= gOriginalPageCountArray[index].iAllocFixed + KAllocPages))
+ {
+ test.Printf(_L("Pass: Correct return value and number of pages allocated is correct\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ Ldd.FreeAllFixedPages();
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call function Epoc::ZoneAllocPhysicalRam() with an invalid aZoneID"));
+ TestStart();
+
+ TUint zoneID = KInvalidZoneID;
+
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, KAllocPages);
+ GetAllPageInfo();
+ if (r == KErrArgument)
+ {
+ test.Printf(_L("Pass: Correct return value\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ Ldd.FreeAllFixedPages();
+ TestEnd();
+
+ test.Next(_L("Test3: Call function Epoc::ZoneAllocPhysicalRam() when aNumPages > zone size"));
+ TestStart();
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ TUint allocPages = gZoneUtilArray[index].iPhysPages + 1;
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, allocPages);
+
+ GetAllPageInfo();
+ if (r == KErrArgument)
+ {
+ test.Printf(_L("Pass: Correct return value and number of pages allocated is correct\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrArgument);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ Ldd.FreeAllFixedPages();
+ TestEnd();
+
+ const TUint KMultiZoneIds = 10;
+ TUint* zoneIdArray = new TUint[KMultiZoneIds];
+ test_NotNull(zoneIdArray);
+
+ test.Next(_L("Test4: Test Epoc::ZoneAllocPhysicaRam() always fails when at least one ID is invalid"));
+ TestStart();
+
+ TBool zonesFound = EFalse;
+ index = gZoneCount - 1;
+ for (; index > 0; index--)
+ {
+ if (gZoneUtilArray[index].iFreePages >= KAllocPages)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TUint zoneIdSize = 2;
+ zoneIdArray[0] = gZoneConfigArray[index].iZoneId;
+ zoneIdArray[1] = KInvalidZoneID;
+ r = Ldd.MultiZoneAllocDiscontiguous(zoneIdArray, zoneIdSize, KAllocPages);
+ if (r != KErrArgument)
+ {// Make sure we cleanup.
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+
+ TestEnd();
+
+ test.Next(_L("Test5: Test Epoc::ZoneAllocPhysicalRam() can span multiple RAM zones"));
+ TestStart();
+ zonesFound = EFalse;
+ TUint zonesCount = 0;
+ const TUint KTest5Zones = 2;
+ TUint zoneIndices[KTest5Zones];
+ allocPages = 0;
+
+ // Attempt to find KTest5Zones RAM zones with some free pages,
+ // search in reverse preference order to reduce chances of kernel heap pages
+ // being allocated into the RAM zones under test.
+ GetPrefOrder();
+ index = gZoneCount - 1;
+ for (; index > 0; index--)
+ {
+ TUint prefIndex = gPrefArray[index];
+ if (gZoneUtilArray[prefIndex].iFreePages != 0)
+ {
+ allocPages += gZoneUtilArray[prefIndex].iFreePages;
+ zoneIndices[zonesCount++] = prefIndex;
+ if (zonesCount == KTest5Zones)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ }
+
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Attempt to find a zone that has less free pages than the allocation
+ // size so we can test that the method continues past too full RAM zones.
+ zonesFound = EFalse;
+ TUint noAllocZone = 0;
+ for (; noAllocZone < gZoneCount; noAllocZone++)
+ {
+ if (allocPages > gZoneUtilArray[noAllocZone].iFreePages &&
+ noAllocZone != zoneIndices[0] && noAllocZone != zoneIndices[1])
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+
+ if (gPagedRom)
+ {// Fill memory with DP pages to test the allocation will discard
+ // pages when necessary.
+ TInt discard;
+ r = AllocDiscardable(discard);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndices[0]].iFreePages != 0 ||
+ gZoneUtilArray[zoneIndices[1]].iFreePages != 0)
+ {
+ test.Printf(_L("r %d\n"), r);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ }
+
+ TUint zoneIds = KTest5Zones;
+ if (!zonesFound)
+ {
+ zoneIdArray[0] = gZoneConfigArray[zoneIndices[0]].iZoneId;
+ zoneIdArray[1] = gZoneConfigArray[zoneIndices[1]].iZoneId;
+ }
+ else
+ {// Have a zone that won't meet the allocation so use it
+ TESTDEBUG(test.Printf(_L("noAllocZone ID %x\n"), gZoneConfigArray[noAllocZone].iZoneId));
+ zoneIds++;
+ zoneIdArray[0] = gZoneConfigArray[noAllocZone].iZoneId;
+ zoneIdArray[1] = gZoneConfigArray[zoneIndices[0]].iZoneId;
+ zoneIdArray[2] = gZoneConfigArray[zoneIndices[1]].iZoneId;
+ }
+
+ // Adjust the allocation size for any kernel heap pages that may be
+ // required as they may get allocated into the RAM zones under test.
+ allocPages -= Ldd.GetAllocDiff(allocPages);
+
+ GetOriginalPageCount();
+ r = Ldd.MultiZoneAllocDiscontiguous(zoneIdArray, zoneIds, allocPages);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gZoneUtilArray[zoneIndices[0]].iAllocFixed <= gOriginalPageCountArray[zoneIndices[0]].iAllocFixed ||
+ gZoneUtilArray[zoneIndices[1]].iAllocFixed <= gOriginalPageCountArray[zoneIndices[1]].iAllocFixed)
+ {// The allocation failed.
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ // TestEnd() will free the allocation of fixed pages.
+ TestEnd();
+
+
+ if (gPagedRom)
+ {
+ test.Next(_L("Test6: Test Epoc::ZoneAllocPhysicalRam() returns KErrNoMemory when DP minimum cache size is hit"));
+ TestStart();
+ GetPrefOrder();
+ TUint zoneFreePages = 0;
+ index = gZoneCount - 1;
+ for (; index > 0; index--)
+ {
+ TUint prefIndex = gPrefArray[index];
+ zoneFreePages = gZoneUtilArray[prefIndex].iFreePages;
+ if (zoneFreePages > 2)
+ {
+ index = prefIndex;
+ zonesFound = ETrue;
+ break;
+ }
+ }
+
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Fill the RAM with DP cache pages and up the minimum cache size so
+ // that the allocation will fail.
+ TInt discardBytes;
+ TInt r = AllocDiscardable(discardBytes, KMaxTUint64, (zoneFreePages - 1) << gPageShift);
+ test_KErrNone(r);
+
+ // Ensure that the RAM zone under test is full.
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages != 0)
+ {
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ r = Ldd.ZoneAllocDiscontiguous(gZoneConfigArray[index].iZoneId, zoneFreePages);
+
+ if (r != KErrNoMemory)
+ {
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test7: Test Epoc::ZoneAllocPhysicalRam() replaces DP cache when DP minimum cache size is hit"));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ GetPrefOrder();
+ zonesFound = EFalse;
+ for (index = gZoneCount - 1; index > 0 && !zonesFound; index--)
+ {
+ TUint prefIndex = gPrefArray[index];
+ zoneFreePages = gZoneUtilArray[prefIndex].iFreePages;
+ if (zoneFreePages > 1)
+ {
+ // Check there is at least one free page in the other RAM zones.
+ TUint i = 0;
+ for (; i < gZoneCount; i++)
+ {
+ if (i != prefIndex && gZoneUtilArray[i].iFreePages != 0)
+ {
+ index = prefIndex;
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ }
+ }
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ index++;
+ // Attempt to allocate a movable page to create a gap for the DP cache
+ // page to be replaced with.
+ GetOriginalPageCount();
+ r = AllocMovable(gChunkArray1, gChunkArraySize1, 1, gPageSize);
+
+ GetAllPageInfo();
+ TESTDEBUG(test.Printf(_L("index %d prev free 0x%x cur free 0x%x\n"),
+ index, gOriginalPageCountArray[index].iFreePages, gZoneUtilArray[index].iFreePages));
+
+ if (r != KErrNone ||
+ gOriginalPageCountArray[index].iFreePages != gZoneUtilArray[index].iFreePages)
+ {// The gap was allocated into the RAM zone under test so can't continue as
+ // the DP cache will attempt to be reallocated into the same RAM zone.
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Get the ldd to create the array for the fixed page addresses here
+ // so that any kernel heap allocations have already occurred before
+ // memory is filled etc. Make allocation really large so it will always be enough.
+ r = Ldd.AllocFixedArray(50);
+
+ // Fill RAM with DP cache pages and free the gap.
+ TInt discardBytes;
+ r = AllocDiscardable(discardBytes, KMaxTUint64, 0);
+ if (r != KErrNone)
+ {
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ UpdateRamInfo();
+ TInt prevFreeBytes = gFreeRam;
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ UpdateRamInfo();
+ TInt freedPages = (gFreeRam - prevFreeBytes) >> gPageShift;
+ if (freedPages < 1)
+ {// Something went wrong as should have freed at least one page
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ TUint extraFreePages = freedPages - 1;
+
+ // Ensure that the RAM zone under test is full.
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages != 0)
+ {
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+
+ // Allocate from the RAM zone which should force a DP cache
+ // page to be allocated.
+ GetOriginalPageCount();
+ TUint fixedAllocPages = 1 + extraFreePages;
+ r = Ldd.ZoneAllocDiscontiguous2(gZoneConfigArray[index].iZoneId, fixedAllocPages);
+
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gOriginalPageCountArray[index].iAllocFixed + fixedAllocPages != gZoneUtilArray[index].iAllocFixed)
+ {
+ test.Printf(_L("r %d index %d alloc 0x%x prevFixed 0x%x curFixed 0x%x\n"), r, index, fixedAllocPages,
+ gOriginalPageCountArray[index].iAllocFixed, gZoneUtilArray[index].iAllocFixed);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ // This should cleanup any fixed pages allocated.
+ TestEnd();
+ }
+
+ test.Next(_L("Test8: Test Epoc::ZoneAllocPhysicalRam() return KErrNoMemory when appropriate"));
+ TestStart();
+ // Search for a RAM zone that has some immovable pages allocated into
+ // it but isn't totally full.
+ GetAllPageInfo();
+ zonesFound = EFalse;
+ for (index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iFreePages &&
+ (gZoneUtilArray[index].iAllocUnknown || gZoneUtilArray[index].iAllocFixed))
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ if (!zonesFound)
+ {
+ test.Printf(_L("Cannot find RAM zones to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ // Attempt to allocate the whole RAM zone.
+ r = Ldd.ZoneAllocDiscontiguous(gZoneConfigArray[index].iZoneId, gZoneUtilArray[index].iPhysPages);
+
+ if (r != KErrNoMemory)
+ {
+ test.Printf(_L("FAIL: r %d index %d\n"), r, index);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test9: Test Epoc::ZoneAllocPhysicalRam() moves the required number of movable pages"));
+ TestStart();
+ TUint allocFixedPages;
+ // Search for a RAM zone that has at least 2 movable pages allocated into it.
+ // Need 2 so that we can move one and leave one.
+ GetAllPageInfo();
+ zonesFound = EFalse;
+ for (index = 0; index < gZoneCount; index++)
+ {
+ if (gZoneUtilArray[index].iAllocMovable > 1)
+ {
+ // Only use this zone if the other RAM zones have enough free space for
+ // the movable page in this zone to be moved to.
+ TUint freeInOther = 0;
+ for (TUint i = 0; i < gZoneCount && !zonesFound; i++)
+ {
+ if (i != index)
+ {
+ freeInOther += gZoneUtilArray[i].iFreePages;
+ }
+ }
+ if (freeInOther >= gZoneUtilArray[index].iAllocMovable)
+ {
+ zonesFound = ETrue;
+ break;
+ }
+ }
+ }
+
+ if (!zonesFound)
+ {
+ test.Printf(_L("No suitable RAM zone could be found - Skipping...\n"));
+ goto skipTest9;
+ }
+
+ // Allocate up to one less than the RAM zone size. Do 2 stage fixed allocation
+ // to avoid kernel heap allocations spoiling test setup.
+ r = Ldd.AllocFixedArray(gZoneConfigArray[index].iPhysPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Not enough free RAM to perform test - Skipping...\n"));
+ goto skipTest9;
+ }
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable < 2)
+ {
+ test.Printf(_L("Expanding kernel heap for phys address array spoiled RAM zone - Skipping...\n"));
+ goto skipTest9;
+ }
+ allocFixedPages = gZoneUtilArray[index].iAllocMovable +
+ gZoneUtilArray[index].iAllocDiscardable +
+ gZoneUtilArray[index].iFreePages - 1;
+ r = Ldd.ZoneAllocDiscontiguous2(gZoneConfigArray[index].iZoneId, allocFixedPages);
+
+ if (r != KErrNone || !gZoneUtilArray[index].iAllocMovable)
+ {
+ test.Printf(_L("Fixed not allocated or too many movable moved RAM zone ID%x\n"),
+ gZoneConfigArray[index].iZoneId);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+
+skipTest9 :
+ // This will clean up any fixed pages allocated.
+ TestEnd();
+
+ delete[] zoneIdArray;
+
+ test.Next(_L("Test10: Test Epoc::ZoneAllocPhysicalRam() (Discontiguous) doesn't affect the allocation of movable pages"));
+ r = TestZoneAllocNoAffect(Z_ALLOC_DISC, BEST_MOVABLE);
+ if (r != KErrNone)
+ {
+ TEST_FAIL;
+ }
+
+ test.Next(_L("Test11: Test Epoc::ZoneAllocPhysicalRam() (Discontiguous) doesn't affect the allocation of discardable pages"));
+ r = TestZoneAllocNoAffect(Z_ALLOC_DISC, BEST_DISCARDABLE);
+ if (r != KErrNone)
+ {
+ TEST_FAIL;
+ }
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestFreeZone
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0537
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the function Epoc::FreePhysicalRam()
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Allocate fixed pages and call function to free all fixed pages allocated.
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrNone
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestFreeZone()
+ {
+ TInt r = 0;
+ TUint zoneID = 0;
+ test.Start(_L("Test1: Free allocated pages"));
+ TestStart();
+
+ TInt pages = 50;
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 &&
+ (gZoneUtilArray[index].iAllocFixed != 0 ||
+ gZoneUtilArray[index].iAllocUnknown != 0 ||
+ (TInt)gZoneUtilArray[index].iFreePages < pages))
+ {
+ -- index;
+ }
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 &&
+ (gZoneUtilArray[index].iAllocFixed != 0 ||
+ gZoneUtilArray[index].iAllocUnknown != 0 ||
+ (TInt)gZoneUtilArray[index].iFreePages < pages))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ TESTDEBUG(test.Printf(_L("Allocating 0x%x pages to zone ID 0x%x\n"), pages, zoneID));
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, pages);
+ GetAllPageInfo();
+
+ TESTDEBUG(test.Printf(_L("Freeing 0x%x fixed pages\n"), pages));
+ if (r == KErrNone)
+ {
+ r = Ldd.FreeZone(pages);
+ }
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Pass: Correct return value\n"));
+ }
+ else
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ }
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestDefragSemMethod
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0538
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the semaphore versions of the various defrag methods
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this, call the semaphore variation of DefragRam.
+//! 2. Fragment the memory. Following this, call the semaphore variation of EmptyRamZone
+//! 3. Fragment the memory. Following this, call the semaphore variation of ClaimRamZone
+//!
+//! @SYMTestExpectedResults
+//! 1. 1 or more zones have been emptied
+//! 2. Zone specified has been emptied
+//! 3. Zone has been claimed
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestDefragSemMethod()
+ {
+ TInt r = 0;
+
+ test.Start(_L("Test1: Call semaphore method of DefragRam"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SEM);
+
+
+ if (r != KErrNone ||(genSucceed && CheckZonesSwitchedOff() == EFalse))
+ {
+ test.Printf(_L("Fail: r = %d, or zones have not been swtiched off\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call semaphore method of EmptyRamZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ TUint defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SEM, defragZoneID);
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && (r != KErrNone || !CheckZoneIsOff(index)))
+ {
+ test.Printf(_L("Fail: r = %d, or zones has not been swtiched off\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ // This will free any allocated memory.
+ TestEnd();
+
+ test.Next(_L("Test3: Call semaphore method of ClaimRamZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 2;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SEM, defragZoneID);
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (CheckZoneIsOff(index) ||
+ (freeInOthers && ( r != KErrNone ||
+ gZoneUtilArray[index].iAllocFixed != gZoneConfigArray[index].iPhysPages)))
+ {
+ test.Printf(_L("Fail: r = %d, or zone ID 0x%x has not been claimed\n"), r, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ r = Ldd.FreeAllFixedPages();
+ }
+
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+
+ }
+
+
+//
+// TestDefragDfcMethod
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0539
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the Dfc versions of the various defrag methods
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory. Following this, call the Dfc variation of DefragRam.
+//! 2. Fragment the memory. Following this, call the Dfc variation of EmptyRamZone
+//! 3. Fragment the memory. Following this, call the Dfc variation of ClaimRamZone
+//!
+//! @SYMTestExpectedResults
+//! 1. 1 or more zones have been emptied
+//! 2. Zone specified has been emptied
+//! 3. Zone has been claimed
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestDefragDfcMethod()
+ {
+ TInt r = 0;
+ TRequestStatus req;
+ test.Start(_L("Test1: Call Dfc method of DefragRam"));
+ TestStart();
+
+ GetAllPageInfo();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetOriginalPageCount();
+ TBool genSucceed = CanGenSucceed();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_DFC, 0, 0, -1, &req);
+ TESTDEBUG(test.Printf(_L("After queueing defrag r = %d\n"), r));
+ User::WaitForRequest(req);
+ r = req.Int();
+
+ if (r != KErrNone || (genSucceed && CheckZonesSwitchedOff() == EFalse))
+ {
+ test.Printf(_L("Fail: r = %d, or zones have not been swtiched off\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test2: Call Dfc method of EmptyRamZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ TUint index = gZoneCount - 1;
+ while (index > 0 &&
+ (gZoneUtilArray[index].iAllocMovable < 10 ||
+ gZoneUtilArray[index].iAllocFixed != 0 ||
+ gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+
+ TUint defragZoneID = gZoneConfigArray[index].iZoneId;
+ test.Printf(_L("zone ID = 0x%x\n"), defragZoneID);
+ if (index == 0 &&
+ (gZoneUtilArray[index].iAllocMovable < 10 ||
+ gZoneUtilArray[index].iAllocFixed != 0 ||
+ gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_DFC, defragZoneID, 0, -1, &req);
+
+ User::WaitForRequest(req);
+ r = req.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && (r != KErrNone || CheckZoneIsOff(index) == EFalse))
+ {
+ test.Printf(_L("Fail: r = %d, or zones have not been swtiched off\n"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ // This will free any allocated memory
+ TestEnd();
+
+
+ test.Next(_L("Test3: Call Dfc method of ClaimRamZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = gZoneCount - 1;
+ while (index > 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ -- index;
+ }
+ defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ if (index == 0 && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ test.Printf(_L("Cannot find zone to perform test, Skipping test step...\n"));
+ }
+ else
+ {
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_DFC, defragZoneID, 0, -1, &req);
+ User::WaitForRequest(req);
+ r = req.Int();
+
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (CheckZoneIsOff(index) ||
+ (freeInOthers && (r != KErrNone ||
+ gZoneUtilArray[index].iAllocFixed != gZoneConfigArray[index].iPhysPages)))
+ {
+ test.Printf(_L("Fail: r = %d, or zone ID 0x%x has not been claimed\n"), r, defragZoneID);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ if (r == KErrNone)
+ {
+ CLEANUP(Ldd.FreeFromAddr( gZoneUtilArray[index].iAllocFixed,
+ gZoneConfigArray[index].iPhysBase));
+ }
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ if (r == KErrNone)
+ {
+ Ldd.FreeFromAddr( gZoneUtilArray[index].iAllocFixed,
+ gZoneConfigArray[index].iPhysBase);
+ }
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestPriorities
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0540
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying the priorities of the defrag methods
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Call DefragRam with a lower invalid priority value, e.g. -2
+//! 2. Call DefragRam with a lower invalid priority value, e.g. 100
+//! 3. Queue three asynchronous defrags using the Dfc method:
+//! a. First one with the lowest priority, this will start the straight away
+//! and will busy the defrag method, causing any other defrag requests to
+//! be queued.
+//! b. Queue a defrag with a relatively low priority
+//! c. Queue a defrag with a higher priority than the one queued in (b)
+//! Record the order in which the defrags are completed
+//!
+//! @SYMTestExpectedResults
+//! 1. KErrArgument
+//! 2. KErrArgument
+//! 3. (a) will complete first as it started straight away.
+//! (b) and (c) were both queued whilst (a) was running,
+//! however as (c) has a higher priority, it will complete first -
+//! therefore the order returned would be "a,c,b"
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestPriorities()
+ {
+ test.Start(_L("Test1: Call defrag with an invalid lower priority"));
+ TestStart();
+
+ TInt r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, 0, -2);
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, not expected\n"), r);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+ TestEnd();
+
+ test.Next(_L("Test2: Call defrag with an invalid higher priority"));
+ TestStart();
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC, 0, 0, 100);
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+ if (r != KErrArgument)
+ {
+ test.Printf(_L("Fail: r = %d, not expected\n"), r);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ TestEnd();
+
+ if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) == 1)
+ {// Only test priorities on single core system as this test is not smp safe.
+ test.Next(_L("Test3: Call Dfc method of EmptyRamZone to test priorities"));
+ TestStart();
+
+
+ TRequestStatus req;
+ TRequestStatus req2;
+ TRequestStatus req3;
+ TInt expectedOrder = 132; // Priorities set in Device driver
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ TUint index = (gZoneCount + 1) / 2;
+ TUint defragZoneID = gZoneConfigArray[index].iZoneId;
+
+ r = Ldd.CheckPriorities(DEFRAG_TYPE_EMPTY, defragZoneID, &req, &req2, &req3);
+
+ User::WaitForRequest(req);
+ User::WaitForRequest(req2);
+ User::WaitForRequest(req3);
+
+ TInt order = Ldd.GetDefragOrder();
+ if (order != expectedOrder)
+ {
+ test.Printf(_L("Fail: order = %d. expected = %d\n"), order, expectedOrder);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ // This will free any allocated memory
+ TestEnd();
+ }
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// TestFlags
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0541
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying that when certain flags are set,
+//! only certain types of pages can be allocated to the zone.
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Set the NoFixed flag in a zone and allocate movable pages
+//! 2. Set the NoFixed flag in a zone and allocate fixed pages
+//! 3. Set the NoFixed flag in a zone and allocate discardable pages
+//! 4. Set the NoFixed flag in a zone and allocate fixed pages to that zone using Epoc::ZoneAllocPhysicalRam()
+//! 5. Set the NoFixed flag in a zone and allocate fixed pages by calling TRamDefragRequest::ClaimRamZone()
+//! 6. Set the NoMovable flag in a zone and allocate movable pages
+//! 7. Set the NoMovable flag in a zone and allocate fixed pages
+//! 8. Set the NoMovable flag in a zone and allocate discardable pages
+//! 9. Set the NoDiscardable flag in a zone and allocate movable pages
+//! 10. Set the NoDiscardable flag in a zone and allocate fixed pages
+//! 11. Set the NoDiscardable flag in a zone and allocate discardable pages
+//! 12. Set the OnlyDiscardable flag in a zone and allocate movable pages
+//! 13. Set the OnlyDiscardable flag in a zone and allocate fixed pages
+//! 14. Set the OnlyDiscardable flag in a zone and allocate discardable pages
+//! 15. Set the OnlyDiscardable flag in a zone and allocate fixed pages to that zone using Epoc::ZoneAllocPhysicalRam()
+//! 16. Set the OnlyDiscardable flag in a zone and allocate fixed pages by calling TRamDefragRequest::ClaimRamZone()
+//! 17. Set the NoFurtherAlloc flag in a zone and allocate movable pages
+//! 18. Set the NoFurtherAlloc flag in a zone and allocate fixed pages
+//! 19. Set the NoFurtherAlloc flag in a zone and allocate discardable pages
+//! 20. Set the NoFurtherAlloc flag in a zone and allocate fixed pages to that zone using Epoc::ZoneAllocPhysicalRam()
+//! 21. Set the NoFurtherAlloc flag in a zone and allocate fixed pages by calling TRamDefragRequest::ClaimRamZone()
+//! 22. Set up memory so that the least preferable RAM zone has movable pages + discardable pages > free pages in the most
+//! preferable zone. Ensure that the discardable pages cannot be discarded and so must be moved. Now set the flag on
+//! all zones barring the most preferable zone to KRamZoneFlagNoMovable, ensuring that most pref has no flags set.
+//! Following this call a general defrag.
+//! 23. Set up memory so that the least preferable RAM zone has movable pages + discardable pages > free pages in the most
+//! preferable RAM zone. Ensure that the discardable pages cannot be discarded and so must be moved.
+//! Now set the flag on all zones barring the most preferable zone to KRamZoneFlagNoDiscard, ensuring that
+//! most preferable RAM zone has no flags set. Following this call a general defrag.
+//! 24. Set up memory so that the least preferable RAM zone has movable pages and discardable pages. Set all the zone
+//! flags to KRamZoneFlagNoMovable. Following this call a general defrag.
+//!
+//! @SYMTestExpectedResults
+//! 1. Movable pages are allocated and no fixed pages allocated
+//! 2. No fixed pages have been allocated
+//! 3. Discardable pages are allocated and no fixed pages allocated
+//! 4. KErrNone, flag is ignored with zone specific allocation
+//! 5. KErrNone, flag is ignored when claiming a zone
+//! 6. No movable pages have been allocated
+//! 7. Fixed pages allocated, no movable allocated
+//! 8. Discardable pages allocated, no movable pages allocated
+//! 9. Movable pages allocated, no discardable pages allocated
+//! 10. Fixed pages allocated, no discardable allocated
+//! 11. No discardable pages allocated
+//! 12. No movable pages allocated
+//! 13. No fixed pages allocated
+//! 14. Discardable pages allocated, no movable or fixed allocated
+//! 15. KErrNone, flag is ignored with zone specific allocation
+//! 16. KErrNone, flag is ignored when claiming a zone
+//! 17. No moving, fixed or discardable pages allocated
+//! 18. No moving, fixed or discardable pages allocated
+//! 19. No moving, fixed or discardable pages allocated
+//! 20. KErrNoMemory, flag is obeyed with zone specific allocation
+//! 21. KErrNone, flag is ignored when claiming a zone
+//! 22. Movable pages moved to the most preferable zone, discardable pages moved to next most preferable zone
+//! 23. Discardable pages moved to most preferable zone, movable pages moved to next next most preferable zone
+//! 24. No pages are moved from the least preferable zone zone
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestFlags()
+ {
+ TInt r = 0;
+ TUint zoneDefragID = 0;
+
+ test.Start(_L("Test1: No Fixed Flag, Alloc Movable"));
+ TestStart();
+
+ TInt index = GetBestZone(BEST_MOVABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ if (SpaceAvailForPageTables(index, KFillAllMovable))
+ {
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ test_KErrNone(r);
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable);
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable == gOriginalPageCountArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Either fixed pages have been allocated or movable pages have not been allocated to zone ID %x\n"), gZoneConfigArray[index].iZoneId);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ else
+ {
+ test.Printf(_L("Skipping...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test2: No Fixed Flag, Alloc Fixed"));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ test_KErrNone(r);
+ }
+
+ // find a zone that has free pages in it to block it
+ GetAllPageInfo();
+ TUint i = 0;
+ for (; i < gZoneCount; i++)
+ {
+ if (gZoneUtilArray[i].iFreePages > 0)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ if (i == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ test_KErrNone(r);
+
+ GetOriginalPageCount();
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+
+ GetAllPageInfo();
+ // Ensure that either zone does not contain extra fixed pages
+ if (gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Fixed pages have been allocated into the zone ID 0x%x r = %d\n"), zoneDefragID, r);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test3: No Fixed Flag, Alloc Discardable"));
+ TestStart();
+ if (gPagedRom)
+ {
+ index = GetBestZone(BEST_DISCARDABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ GetOriginalPageCount();
+
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ test_KErrNone(r);
+
+ UpdateRamInfo();
+ TInt discardablePages;
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Fixed pages have been allocated\n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test4: No Fixed Flag, Alloc Fixed using ZoneAllocPhyicalRam"));
+ TestStart();
+
+ index = GetBestZone(BEST_FIXED);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ test_KErrNone(r);
+
+ // Just need to try and allocate one page
+ r = Ldd.ZoneAllocDiscontiguous(zoneDefragID, 1);
+
+ GetAllPageInfo();
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: Fixed pages have not been allocated into the zone\n"));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test5: No Fixed Flag, Alloc Fixed by attempting to claim zone"));
+ TestStart();
+
+ GetAllPageInfo();
+ index = 0;
+ while ((TUint)index < gZoneCount && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ index++;
+ }
+
+ if ((TUint)index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_FIXED_FLAG);
+ test_KErrNone(r);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, zoneDefragID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r != KErrNone)
+ {
+ test.Printf(_L("Fail: Claim zone ID 0x%x was unsuccessful, r = %d\n"), zoneDefragID, r);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+
+//------------------------------------------------------------
+ test.Next(_L("Test6: No Movable Flag, Alloc Movable"));
+ TestStart();
+
+ index = GetBestZone(BEST_MOVABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_MOVE_FLAG);
+ test_KErrNone(r);
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable, KChunkDefaultSize, EFalse);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable)
+ {
+ test.Printf(_L("Fail: Movable pages have been allocated in the zone\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test7: No Movable Flag, Alloc Fixed"));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ test_KErrNone(r);
+ }
+
+ index = GetBestZone(BEST_FIXED);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_MOVE_FLAG);
+ test_KErrNone(r);
+
+ GetOriginalPageCount();
+ // Fill up all of RAM with fixed pages.
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+ test.Printf(_L("r = %d\n"), r);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocFixed <= gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: orig mov 0x%x fix 0x%x current mov 0x%x fix 0x%x\n"), gOriginalPageCountArray[index].iAllocMovable,
+ gOriginalPageCountArray[index].iAllocFixed, gZoneUtilArray[index].iAllocMovable, gZoneUtilArray[index].iAllocFixed);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test8: No Movable Flag, Alloc Discardable"));
+ TestStart();
+ if (gPagedRom)
+ {
+ index = GetBestZone(BEST_DISCARDABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_MOVE_FLAG);
+ test_KErrNone(r)
+ UpdateRamInfo();
+ TInt discardablePages;
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable)
+ {
+ test.Printf(_L("Fail: Movable pages have been allocated into the zone \n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+//-----------------------------------------------------------------------------------------------
+
+ test.Next(_L("Test9: No Discardable Flag, Alloc Movable"));
+ TestStart();
+
+ index = GetBestZone(BEST_MOVABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_DISCARD_FLAG);
+ test_KErrNone(r);
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable);
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocDiscardable > gOriginalPageCountArray[index].iAllocDiscardable ||
+ (gZoneUtilArray[index].iAllocMovable <= gOriginalPageCountArray[index].iAllocMovable &&
+ gZoneUtilArray[index].iAllocFixed == gOriginalPageCountArray[index].iAllocFixed))
+ {
+ test.Printf(_L("Fail: Either discardable pages have been allocated or movable pages have not been allocated\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test10: No Discardable Flag, Alloc Fixed"));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ test_KErrNone(r);
+ }
+
+ index = GetBestZone(BEST_FIXED);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_DISCARD_FLAG);
+ test_KErrNone(r);
+ // Fill up all of RAM with fixed pages.
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable > gOriginalPageCountArray[index].iAllocDiscardable ||
+ gZoneUtilArray[index].iAllocFixed <= gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Discardable pages have been allocated or fixed pages have not been allocated\n"));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test11: No Discardable Flag, Alloc Discardable"));
+ TestStart();
+ if (gPagedRom)
+ {
+ index = GetBestZone(BEST_DISCARDABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_DISCARD_FLAG);
+ test_KErrNone(r);
+ UpdateRamInfo();
+
+ TInt discardablePages;
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNoMemory)
+ {// Allocation should fail as no dis flag is set
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocDiscardable > gOriginalPageCountArray[index].iAllocDiscardable)
+ {
+ test.Printf(_L("Fail: Discardable pages have been allocated into the zone\n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+//-----------------------------------------------------------------------------------------------
+
+ test.Next(_L("Test12: Only Discardable Flag, Alloc Movable"));
+ TestStart();
+
+ index = GetBestZone(BEST_MOVABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ test_KErrNone(r);
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable, KChunkDefaultSize, EFalse);
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable)
+ {
+ test.Printf(_L("Fail: Movable pages have been allocated\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test13: Only Discardable Flag, Alloc Fixed"));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ test_KErrNone(r);
+ }
+
+ index = GetBestZone(BEST_FIXED);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ test_KErrNone(r);
+
+ // Fill up all of RAM with fixed pages.
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Fixed pages have been allocated\n"));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test14: Only Discardable Flag, Alloc Discardable"));
+ TestStart();
+ if (gPagedRom)
+ {
+ index = GetBestZone(BEST_DISCARDABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ test_KErrNone(r);
+ UpdateRamInfo();
+
+ TInt discardablePages;
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Pages other than discardable have been allocated\n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+ test.Next(_L("Test15: Only Discardable Flag, Alloc Fixed using ZoneAllocPhyicalRam"));
+ TestStart();
+
+ index = GetBestZone(BEST_FIXED);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ test_KErrNone(r);
+
+ // Just need to try and allocate one page
+ r = Ldd.ZoneAllocDiscontiguous(zoneDefragID, 1);
+
+ GetAllPageInfo();
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: Fixed pages have not been allocated into zone ID 0x%x\n"), zoneDefragID);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test16: Only Discardable Flag, Alloc Fixed by attempting to claim zone"));
+ TestStart();
+
+ GetAllPageInfo();
+ index = 0;
+ while ((TUint)index < gZoneCount && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ index++;
+ }
+
+ if ((TUint)index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, ONLY_DISCARD_FLAG);
+ test_KErrNone(r);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, zoneDefragID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r != KErrNone)
+ {
+ test.Printf(_L("Fail: Claim zone ID 0x%x was unsuccessful, r = %d\n"), zoneDefragID, r);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+//-----------------------------------------------------------------------------------------------
+
+ test.Next(_L("Test17: No further alloc Flag, Alloc Movable"));
+ TestStart();
+
+ index = GetBestZone(BEST_MOVABLE);
+
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_ALLOC_FLAG);
+ test_KErrNone(r);
+ AllocMovable(gChunkArray1, gChunkArraySize1, KFillAllMovable, KChunkDefaultSize, EFalse);
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocDiscardable > gOriginalPageCountArray[index].iAllocDiscardable ||
+ gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Pages been allocated\n"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test18: No further alloc Flag, Alloc Fixed"));
+ TestStart();
+
+ if(gPagedRom)
+ {
+ r = DPTest::SetCacheSize(gOriginalMinCacheSize, gOriginalMinCacheSize);
+ test_KErrNone(r);
+ }
+
+ // Find a zone with free pages and set the flag on this zone
+ // as it will ensure that you cannot fill all of free RAM with fixed pages
+ index = KErrNotFound;
+ GetAllPageInfo();
+ for (TUint i = 0; i < gZoneCount; i++)
+ {
+ if (gZoneUtilArray[i].iFreePages != 0)
+ {
+ index = i;
+ break;
+ }
+ }
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_ALLOC_FLAG);
+ test_KErrNone(r);
+
+ GetOriginalPageCount();
+ r = Ldd.AllocateFixed(FILL_ALL_FIXED);
+
+ // Ensure memory wasn't filled as it should have hit the blocked zone.
+ GetAllPageInfo();
+ if (r != KErrNoMemory || gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: orig fix 0x%x current fix 0x%x\n"), gOriginalPageCountArray[index].iAllocFixed, gZoneUtilArray[index].iAllocFixed);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test19: No further alloc Flag, Alloc Discardable"));
+ TestStart();
+ if (gPagedRom)
+ {
+ index = GetBestZone(BEST_DISCARDABLE);
+
+ if (index == KErrNotFound)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_ALLOC_FLAG);
+ test_KErrNone(r);
+ UpdateRamInfo();
+ TInt discardablePages;
+ r = AllocDiscardable(discardablePages);
+ if (r != KErrNoMemory)
+ {// Allocation should fail as no alloc flag is set
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ GetAllPageInfo();
+
+ if (gZoneUtilArray[index].iAllocDiscardable > gOriginalPageCountArray[index].iAllocDiscardable ||
+ gZoneUtilArray[index].iAllocMovable > gOriginalPageCountArray[index].iAllocMovable ||
+ gZoneUtilArray[index].iAllocFixed > gOriginalPageCountArray[index].iAllocFixed)
+ {
+ test.Printf(_L("Fail: Pages have been allocated into the zone\n"));
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ }
+ else
+ {
+ test.Printf(_L("Not a paged ROM - Skipping test step\n"));
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test20: No Further Alloc Flag, Alloc Fixed using ZoneAllocPhyicalRam"));
+ TestStart();
+
+ GetAllPageInfo();
+ index = 0;
+ while ((TUint)index < gZoneCount && (gZoneUtilArray[index].iFreePages == 0 ||
+ gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ index++;
+ }
+
+ if ((TUint)index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+
+ GetOriginalPageCount();
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_ALLOC_FLAG);
+ test_KErrNone(r);
+
+ // Just need to try and allocate one page
+ r = Ldd.ZoneAllocDiscontiguous(zoneDefragID, 1);
+
+ GetAllPageInfo();
+ if (r != KErrNoMemory)
+ {
+ test.Printf(_L("Fail: Fixed pages have been allocated into zone ID 0x%x\n"), zoneDefragID);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test21: No Further Alloc Flag, Alloc Fixed by attempting to claim zone"));
+ TestStart();
+
+ GetAllPageInfo();
+ index = 0;
+ while ((TUint)index < gZoneCount && (gZoneUtilArray[index].iAllocFixed != 0 || gZoneUtilArray[index].iAllocUnknown != 0))
+ {
+ index++;
+ }
+
+ if ((TUint)index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneDefragID = gZoneConfigArray[index].iZoneId;
+ r = Ldd.SetZoneFlag(zoneDefragID, gZoneConfigArray[index].iFlags, NO_ALLOC_FLAG);
+ test_KErrNone(r);
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, zoneDefragID);
+ GetAllPageInfo();
+ TUint freeInOthers = gTotalPageCount.iFreePages - gZoneUtilArray[index].iFreePages;
+ if (freeInOthers && r != KErrNone)
+ {
+ test.Printf(_L("Fail: Claim zone ID 0x%x was unsuccessful, r = %d\n"), zoneDefragID, r);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ TUint mostPrefArrayIndex = 0;
+ TUint mostPrefIndex = 0;
+ TUint leastPrefIndex = 0;
+ const TUint KFreeMostPref = 10;
+ TUint flag = 0;
+ TUint prefIndex;
+ TUint totalFree;
+
+
+ for (TUint testStep = 0; testStep < 2; testStep++)
+ {
+ switch(testStep)
+ {
+ case 0:
+ test.Next(_L("Test22: Ensure that the General Defrag looks at the flags 1"));
+ break;
+
+ case 1:
+ test.Next(_L("Test23: Ensure that the General Defrag looks at the flags 2"));
+ break;
+ }
+
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+ TUint freeNeededInMostPref = 0;
+ if (!gPagedRom)
+ {
+ test.Printf(_L("Not a paged ROM - Skipping...\n"));
+ goto skipTest22;
+ }
+
+ // Find the most pref zone with free pages
+ r = FindMostPrefWithFree(mostPrefIndex, &mostPrefArrayIndex);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Cannot find zone with free pages - Skipping...\n"));
+ goto skipTest22;
+ }
+
+ // Ensure that the least pref zone is empty
+ leastPrefIndex = gPrefArray[gZoneCount - 1];
+ if (gZoneUtilArray[leastPrefIndex].iFreePages != gZoneUtilArray[leastPrefIndex].iPhysPages)
+ {
+ test.Printf(_L("Least pref zone is not empty - Skipping...\n"));
+ goto skipTest22;
+ }
+
+ // Allocate 1 movable page to the least preferable zone
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, leastPrefIndex, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate movable r = %d - Skipping...\n"), r);
+ goto skipTest22;
+ }
+
+ // Allocate 1 discardable page to the least preferable zone
+ if (gZoneUtilArray[leastPrefIndex].iFreePages != 0)
+ {
+ TInt disPages;
+ r = ZoneAllocDiscard(leastPrefIndex, 1, disPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate discardable pages r = %d - Skipping...\n"), r);
+ goto skipTest22;
+ }
+
+ // up the minimum cache size so that the pages have to be moved - not discarded
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ r = DPTest::SetCacheSize(currentCacheSize, currentCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set cache size r = %d - Skipping...\n"), r);
+ goto skipTest22;
+ }
+ }
+ else
+ {
+ test.Printf(_L("Least pref zone has no free pages - Skipping...\n"));
+ goto skipTest22;
+ }
+
+ // Check that the least pref zone has movable and discardable pages in it
+ GetAllPageInfo();
+ if (gZoneUtilArray[leastPrefIndex].iAllocMovable == 0 ||
+ gZoneUtilArray[leastPrefIndex].iAllocDiscardable == 0)
+ {
+ test.Printf(_L("No movable or discardable in least pref zone\n"));
+ PrintPageInfo();
+ goto skipTest22;
+ }
+
+ ResetRamZoneFlags();
+ // if most pref zone has too many free pages fill up with fixed
+ if (gZoneUtilArray[mostPrefIndex].iFreePages > KFreeMostPref)
+ {
+ TUint allocPages = gZoneUtilArray[mostPrefIndex].iFreePages - KFreeMostPref;
+ r = Ldd.ZoneAllocToMany(mostPrefIndex, allocPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed allocate 0x%x fixed to index %d r = %d - Skipping...\n"),
+ allocPages, mostPrefIndex,r);
+ PrintPageInfo();
+ goto skipTest22;
+ }
+ }
+
+
+ // if the no. of discardable pages is less than free in most pref increase the min cache size
+ GetAllPageInfo();
+ if (gZoneUtilArray[leastPrefIndex].iAllocDiscardable < gZoneUtilArray[mostPrefIndex].iFreePages)
+ {
+ TUint discDiff = gZoneUtilArray[mostPrefIndex].iFreePages - gZoneUtilArray[leastPrefIndex].iAllocDiscardable;
+ test.Printf(_L("discDiff = 0x%x\n"), discDiff);
+ TInt disPages;
+ if (ZoneAllocDiscard(leastPrefIndex, discDiff, disPages) != KErrNone)
+ {
+ test.Printf(_L("Failed allocate discardable to zone index %d- Skipping...\n"), leastPrefIndex);
+ goto skipTest22;
+ }
+ // up the minimum cache size by the difference as we don't want these pages to be discarded
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ r = DPTest::SetCacheSize(currentCacheSize, currentCacheSize);
+ test.Printf(_L("r = %d\n"), r);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set cache size r = %d - Skipping...\n"), r);
+ goto skipTest22;
+ }
+ }
+ ResetRamZoneFlags();
+
+ // if the rest of the zones are either full or empty put a fixed page into the next most pref empty zone
+ GetPrefOrder();
+ prefIndex = 0;
+ totalFree = 0;
+ for (; prefIndex < gZoneCount && totalFree < gZoneUtilArray[leastPrefIndex].iAllocDiscardable; prefIndex++)
+ {// Look for zone that has enough free pages to fit all the discardable
+ TUint zoneIndex = gPrefArray[prefIndex];
+ if (zoneIndex != mostPrefIndex && zoneIndex != leastPrefIndex)
+ {
+ if (gZoneUtilArray[zoneIndex].iFreePages != gZoneUtilArray[zoneIndex].iPhysPages)
+ {
+ totalFree += gZoneUtilArray[zoneIndex].iFreePages;
+ }
+ else
+ {
+ r = Ldd.ZoneAllocToMany(zoneIndex, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Couldn't alloc fixed to zone index %d - r = %d\n"), zoneIndex, r);
+ goto skipTest22;
+ }
+ GetAllPageInfo();
+ totalFree += gZoneUtilArray[zoneIndex].iFreePages;
+ }
+ }
+ }
+
+ if (prefIndex >= gZoneCount)
+ {
+ test.Printf(_L("Couldn't find zone\n"));
+ goto skipTest22;
+ }
+
+
+
+ // If the most preferable zone does not have enough free pages, skip
+ freeNeededInMostPref = (testStep == 0) ? gZoneUtilArray[leastPrefIndex].iAllocMovable : gZoneUtilArray[leastPrefIndex].iAllocDiscardable;
+ if (gZoneUtilArray[mostPrefIndex].iFreePages < freeNeededInMostPref)
+ {
+ test.Printf(_L("Free needed in mostPref(%d) = %d, Free available in mostPref = %d - skipping...\n"),
+ mostPrefIndex,freeNeededInMostPref,gZoneUtilArray[mostPrefIndex].iFreePages);
+ goto skipTest22;
+ }
+
+ GetAllPageInfo();
+ // Set up the RAM zone flags for the test
+ flag = (testStep == 0)? NO_MOVE_FLAG: NO_DISCARD_FLAG;
+ // Set all zones except most pref to KRamZoneFlagNoMovable or KRamZoneFlagNoDiscard
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ if (index != mostPrefIndex)
+ {
+ r = Ldd.SetZoneFlag(zoneID, gZoneConfigArray[index].iFlags, flag);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set flag r = %d - Skipping...\n"), r);
+ goto skipTest22;
+ }
+ }
+ }
+
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ GetAllPageInfo();
+ switch(testStep)
+ {
+ case 0:
+ if (r != KErrNone ||
+ gOriginalPageCountArray[mostPrefIndex].iAllocMovable >= gZoneUtilArray[mostPrefIndex].iAllocMovable ||
+ gZoneUtilArray[leastPrefIndex].iFreePages != gZoneUtilArray[leastPrefIndex].iPhysPages)
+ {
+ test.Printf(_L("FAIL:r=%d MostPref(%d): origMov 0x%x curMov 0x%x LeastPref(%d): origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"),
+ r, mostPrefIndex, gOriginalPageCountArray[mostPrefIndex].iAllocMovable, gZoneUtilArray[mostPrefIndex].iAllocMovable,
+ leastPrefIndex, gOriginalPageCountArray[leastPrefIndex].iAllocMovable, gZoneUtilArray[leastPrefIndex].iAllocMovable,
+ gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable, gZoneUtilArray[leastPrefIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ break;
+
+ case 1:
+ if (r != KErrNone ||
+ gOriginalPageCountArray[mostPrefIndex].iAllocDiscardable >= gZoneUtilArray[mostPrefIndex].iAllocDiscardable ||
+ gZoneUtilArray[leastPrefIndex].iFreePages != gZoneUtilArray[leastPrefIndex].iPhysPages)
+ {
+ test.Printf(_L("FAIL:r=%d MostPref(%d): origMov 0x%x curMov 0x%x LeastPref(%d): origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"),
+ r, mostPrefIndex, gOriginalPageCountArray[mostPrefIndex].iAllocMovable, gZoneUtilArray[mostPrefIndex].iAllocMovable,
+ leastPrefIndex, gOriginalPageCountArray[leastPrefIndex].iAllocMovable, gZoneUtilArray[leastPrefIndex].iAllocMovable,
+ gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable, gZoneUtilArray[leastPrefIndex].iAllocDiscardable);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ break;
+ }
+
+ skipTest22:
+ TestEnd();
+ }
+
+ test.Next(_L("Test24: Ensure that the General Defrag doesnt move or discard pages if KRamZoneFlagNoMovable set on all zones "));
+ TestStart();
+ gChunkArray1 = new RChunk;
+ gChunkArraySize1 = 1;
+ // Find the most pref zone with free pages
+ GetPrefOrder();
+ TInt disPages = 0;
+ if (FindMostPrefWithFree(mostPrefIndex, &mostPrefArrayIndex) != KErrNone)
+ {
+ test.Printf(_L("Cannot find zone with free pages - Skipping...\n"));
+ goto skipTest24;
+ }
+
+ // Ensure that the least pref zone has free pages in it
+ leastPrefIndex = gPrefArray[gZoneCount-1];
+ if (gZoneUtilArray[leastPrefIndex].iFreePages == 0)
+ {
+ test.Printf(_L("Least pref zone has no free pages - Skipping...\n"));
+ goto skipTest24;
+ }
+
+ // Allocate 1 movable page to the least preferable zone
+ r = ZoneAllocMovable(gChunkArray1, gChunkArraySize1, leastPrefIndex, 1);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate movable page r = %d - Skipping...\n"), r);
+ goto skipTest24;
+ }
+
+ if (gPagedRom)
+ {
+
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+ // Allocate 1 discardable page to the least preferable zone
+ if (gZoneUtilArray[leastPrefIndex].iFreePages != 0)
+ {
+ r = ZoneAllocDiscard(leastPrefIndex, 1, disPages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Discardable pages not allocated r= %d\n"), r);
+ }
+
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ r = DPTest::SetCacheSize(currentCacheSize, currentCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set cache size r = %d - Skipping...\n"), r);
+ goto skipTest24;
+ }
+ }
+ }
+
+
+ // Check that the least pref zone has movable and discardable (if allocated) pages in it
+ GetAllPageInfo();
+ if (gZoneUtilArray[leastPrefIndex].iAllocMovable == 0 ||
+ gZoneUtilArray[leastPrefIndex].iAllocDiscardable < (TUint)disPages ||
+ gZoneUtilArray[leastPrefIndex].iAllocMovable > gTotalPageCount.iFreePages - gZoneUtilArray[leastPrefIndex].iFreePages)
+ {
+ test.Printf(_L("No movable in least pref zone or no space for moveable pages to be moved to\n"));
+ PrintPageInfo();
+ goto skipTest24;
+ }
+
+ ResetRamZoneFlags();
+ GetAllPageInfo();
+ // Now set all zones to KRamZoneFlagNoMovable
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ r = Ldd.SetZoneFlag(zoneID, gZoneConfigArray[index].iFlags, NO_MOVE_FLAG);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to set cache size r = %d - Skipping...\n"), r);
+ goto skipTest24;
+ }
+ }
+
+ GetOriginalPageCount();
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ GetAllPageInfo();
+ if (r != KErrNone ||
+ gOriginalPageCountArray[leastPrefIndex].iAllocMovable != gZoneUtilArray[leastPrefIndex].iAllocMovable ||
+ gZoneUtilArray[leastPrefIndex].iAllocDiscardable < gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable)
+ {
+ test.Printf(_L("FAIL:r=%d LeastPref(%d): origMov 0x%x curMov 0x%x origDis 0x%x curDis 0x%x\n"),
+ r,leastPrefIndex, gOriginalPageCountArray[leastPrefIndex].iAllocMovable, gZoneUtilArray[leastPrefIndex].iAllocMovable,
+ gOriginalPageCountArray[leastPrefIndex].iAllocDiscardable, gZoneUtilArray[leastPrefIndex].iAllocDiscardable);
+ CLEANUP(ResetRamZoneFlags());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+skipTest24:
+ TestEnd();
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// Template functions encapsulating ControlIo magic
+//
+template <class C>
+TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
+ {
+ TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
+
+ TInt r = fs.ControlIo(drv, fkn, ptrC);
+
+ return r;
+ }
+
+//
+// FormatMMC
+//
+// Formats the MMC card
+//
+void FormatMMC()
+ {
+ test.Printf(_L("Formatting MMC...\n"));
+
+ RFs theFs;
+ TBuf<4> driveBuf = _L("D:\\");
+ RFormat format;
+ TInt count;
+ TChar driveLet;
+
+ TInt r = theFs.Connect();
+ test_KErrNone(r);
+
+ r = theFs.DriveToChar(gDrive, driveLet);
+ test_KErrNone(r);
+
+ driveBuf[0] = driveLet;
+ test.Printf(_L("Formatting Drive: %C\n"),(TInt)driveLet);
+
+ r = format.Open(theFs,driveBuf,EFullFormat,count);
+ test_KErrNone(r);
+
+ while(count)
+ {
+ TInt r = format.Next(count);
+ test_KErrNone(r);
+ }
+ format.Close();
+ theFs.Close();
+ }
+
+
+//
+// FileNameGen
+//
+// Generates file names to create the files
+//
+void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos)
+ {
+ TInt padding;
+ TInt i = 0;
+ TBuf16<10> tempbuf;
+
+ _LIT(KNumber,"%d");
+ tempbuf.Format(KNumber,aPos);
+
+ padding = aLong-tempbuf.Size()/2;
+ aBuffer = _L("");
+
+ while(i < padding)
+ {
+ aBuffer.Append('F');
+ i++;
+ }
+ aBuffer.Append(tempbuf);
+
+ _LIT(KExtension1, ".TXT");
+ aBuffer.Append(KExtension1);
+ }
+
+
+//
+// CreateFiles
+//
+// Creates the files to fill part of the read cache
+//
+void CreateFiles(TInt aFiles, TInt aFileSize)
+ {
+ TInt i = 0, r = 0;
+ RFile file;
+ TBuf16<50> directory;
+
+ TBuf16<50> path;
+ TBuf16<50> buffer(50);
+
+ directory = gSessionPath;
+
+ test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), aFiles, aFileSize);
+
+ // create a big buffer to speed things up
+ HBufC8* bigBuf = NULL;
+ const TInt KBigBufferSize = 32 * 1024;
+ TRAPD(res,bigBuf = HBufC8::NewL(KBigBufferSize));
+ test(res == KErrNone && bigBuf != NULL);
+
+ TPtr8 bigBufWritePtr(NULL, 0);
+ bigBufWritePtr.Set(bigBuf->Des());
+
+ // Fill the buffer
+ TChar aC = 'A';
+ for(i = 0; i < KBigBufferSize; i++)
+ {
+ bigBufWritePtr.Append((i%32) + aC);
+ }
+
+
+ i = 0;
+ while(i < aFiles)
+ {
+ if (i % 10 == 0)
+ test.Printf(_L("Creating file %d of %d...\r"), i, aFiles);
+ FileNameGen(buffer, 8, i+3) ;
+ path = directory;
+ path.Append(buffer);
+
+ // delete file first to ensure it's contents are not in the cache (file may be on the closed file queue)
+ r = gTheFs.Delete(path);
+ test(r == KErrNone || r == KErrNotFound);
+
+ r = file.Create(gTheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
+ if(r == KErrAlreadyExists)
+ r = file.Open(gTheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
+ TInt j = 0;
+ i++;
+ while(j < aFileSize)
+ {
+ bigBufWritePtr.SetLength(Min(KBigBufferSize, aFileSize - j));
+ r = file.Write(bigBufWritePtr);
+ // Running out of disk space is expected for the last file.
+ // Premature "disk full" conditions need to abort.
+ if (r == KErrDiskFull)
+ {
+ test(i == aFiles);
+ break;
+ }
+ test_KErrNone(r);
+ j += bigBufWritePtr.Length();
+ }
+
+ file.Close();
+ }
+ test.Printf(_L("\nFiles created\n"));
+ delete bigBuf;
+ }
+
+
+//
+// FillCache
+//
+// Allocate discardable pages using file system caching
+//
+TInt FillCache(TInt aFiles, TInt aFileSize)
+ {
+ // Fail if files already open
+ test(!gFileCacheRun);
+
+
+ TInt i = 0, r = 0;
+ TBuf16<50> directory;
+
+ TBuf16<50> path;
+ TBuf16<50> buffer(50);
+ HBufC8* buf = NULL;
+ TPtr8 bufPtr(NULL, 0);
+
+ TRAPD(res,buf = HBufC8::NewL(2));
+ test(res == KErrNone && buf != NULL);
+ bufPtr.Set(buf->Des());
+
+ TESTDEBUG(test.Printf(_L("Filling the cache\n")));
+
+ directory = gSessionPath;
+
+ i = 0;
+
+ GetAllPageInfo();
+ TESTDEBUG(test.Printf(_L("total disc pages = %d\n"), gTotalPageCount.iDiscardablePages));
+
+
+ while(i < aFiles)
+ {
+ FileNameGen(buffer, 8, i+3) ;
+ path = directory;
+ path.Append(buffer);
+ r = gFile[i].Open(gTheFs,path,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
+ test_KErrNone(r);
+
+ TInt j = 0;
+ while(j < aFileSize)
+ {
+ r = gFile[i].Read(j,bufPtr);
+ test_KErrNone(r);
+ j += 4 * 1024;
+ }
+ i++;
+ }
+ gFileCacheRun = ETrue;
+ GetAllPageInfo();
+ TESTDEBUG(test.Printf(_L("after - total disc pages = %d\n"), gTotalPageCount.iDiscardablePages));
+ delete buf;
+ TESTDEBUG(test.Printf(_L("Cache filled\n")));
+
+#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
+ // get number of items on Page Cache
+ TFileCacheStats startPageCacheStats;
+
+ r = controlIo(gTheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
+ test.Printf(_L("control stats r= %d\n"), r);
+ test(r==KErrNone || r == KErrNotSupported);
+
+ TESTDEBUG(test.Printf(_L("Allocated segment count=%d\n"),startPageCacheStats.iAllocatedSegmentCount));
+#endif
+ // if we do not have any discardable pages then something went
+ // wrong with file caching
+ if (gTotalPageCount.iDiscardablePages == 0)
+ return KErrNotSupported;
+
+ return KErrNone;
+ }
+
+
+
+//
+// SetUpMMC
+//
+// Sets up the MMC to be used by the test by creating files on the MMC
+//
+void SetUpMMC()
+ {
+ FormatMMC();
+
+ TInt r = 0;
+
+ TChar driveToTest;
+
+ TVolumeInfo volInfo;
+
+ r = gTheFs.DriveToChar(gDrive, driveToTest);
+ test_KErrNone(r);
+
+ r = gTheFs.CharToDrive(driveToTest,gDrive);
+ test_KErrNone(r);
+
+ gSessionPath = _L("?:\\F32-TST\\");
+ gSessionPath[0] = (TUint16) driveToTest;
+ test.Printf(_L("Drive Letter=%C\n"),(TInt)driveToTest);
+
+ TDriveInfo info;
+ r = gTheFs.Drive(info,gDrive);
+ test_KErrNone(r);
+ r = gTheFs.SetSessionPath(gSessionPath);
+ test_KErrNone(r);
+ r = gTheFs.MkDirAll(gSessionPath);
+ if (r != KErrNone && r != KErrAlreadyExists)
+ {
+ test_KErrNone(r);
+ }
+
+ r = gTheFs.Volume(volInfo, gDrive);
+ test_KErrNone(r);
+ TInt64 gMediaSize = volInfo.iSize;
+
+ // This calculation is approximate because the client cannot know
+ // internal allocation mechanisms of the filesystem, i.e. how much
+ // metadata is associated with a file of name X / size Y, whether
+ // space used by such metadata is reflected in TDriveInfo::iSize and
+ // what block/clustersize the filesystem will round filesizes to.
+ // The last file that fills up the drive may therefore be partial
+ // (smaller than this calculation predicts).
+ TInt maxPossibleFiles = gFilesNeededToFillCache;
+ test.Printf(_L("Original files needed = %d\n"), maxPossibleFiles);
+ if(gMediaSize < (KDefaultCacheSize * maxPossibleFiles))
+ {
+ maxPossibleFiles = (gMediaSize - 10) / KDefaultCacheSize;
+ test.Printf(_L("Disk size is smaller - files needed = %d\n"), maxPossibleFiles);
+ }
+ gFilesNeededToFillCache = maxPossibleFiles;
+ CreateFiles(gFilesNeededToFillCache, KDefaultCacheSize);
+ }
+
+
+//
+// TestFileCaching
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0599
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying that when File System Caching allocates dicardable pages,
+//! Defrag and allocation of fixed pages happens correctly.
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fill the file system cache to allocate discardable pages
+//! following this call EmptyRamZone() in a zone with discardable pages.
+//! 2. Fill the file system cache to allocate discardable pages
+//! folling this allocate discontiguous fixed pages to a zone
+//! 3. Fill the file system cache to allocate discardable pages
+//! . following this allocate discontuguous fixed pages
+//! 4. Fill the file system cache to allocate discardable pages
+//! following this allocate less than 16 contiguous fixed pages
+//! 5. Fill the file system cache to allocate discardable pages
+//! following this allocate more than 16 contiguous fixed pages
+//!
+//! @SYMTestExpectedResults
+//! 1. Discardable pages are removed
+//! 2. KErrNone
+//! 3. KErrNone
+//! 4. KErrNone and numDiscardablePages != 0
+//! 5. KErrNone and numDiscardablePages = 0
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestFileCaching()
+ {
+ const TUint KDisPagesReq = 1;
+ TInt r = KErrNone;
+ TInt allocSize = 0;
+ TUint zoneID = 0;
+ TUint index = 0;
+ TUint minDiscardPages = 0;
+ if (gDrive == KNoRemovableDrive)
+ {
+ test.Start(_L("Cannot find drive to write files to - Skipping FS Caching Tests\n"));
+ test.End();
+ return 0;
+ }
+
+ r = gTheFs.Connect();
+ test_KErrNone(r);
+
+ SetUpMMC();
+
+ RRamDefragFuncTestLdd Ldd2;
+ r = Ldd2.Open();
+ test_KErrNone(r);
+
+ test.Start(_L("Test1: Test EmptyRamZone() clears file server cache pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ r = FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("File system caching failed - Skipping all file caching tests...\n"));
+ goto skipFileCacheTests;
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ while (index < gZoneCount && gZoneUtilArray[index].iAllocDiscardable < KDisPagesReq)
+ {
+ ++ index;
+ }
+
+ if (index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test on - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, zoneID);
+
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iAllocDiscardable != 0)
+ {
+ test.Printf(_L("Fail: Zone ID 0x%x has 0x%x discardable pages\n"), zoneID, gZoneUtilArray[index].iAllocDiscardable);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ }
+ TestEnd();
+
+ test.Next(_L("Test2: Filling the FS Cache and allocating fixed pages to a zone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ r = FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("File system caching failed - Skipping all file caching tests...\n"));
+ goto skipFileCacheTests;
+ }
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ index = 0;
+ while (index < gZoneCount && gZoneUtilArray[index].iAllocDiscardable < KDisPagesReq)
+ {
+ ++ index;
+ }
+
+ if (index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test on - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ // Just need to attempt to allocate one more page than there is free in the zone
+ allocSize = gZoneUtilArray[index].iFreePages + 1;
+
+ test.Printf(_L("Allocating 0x%x fixed pages to zone ID 0x%x.....\n"), allocSize, zoneID);
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, allocSize);
+ test.Printf(_L("r = %d\n"), r);
+
+ GetAllPageInfo();
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: Fixed pages have not been allocated, r = %d, expected = %d\n"), r, KErrNone);
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ TESTDEBUG(test.Printf(_L("Freeing all Fixed Pages.....\n")));
+ Ldd.FreeAllFixedPages();
+ }
+ TestEnd();
+
+
+ test.Next(_L("Test3: Filling the FS Cache and allocating fixed pages"));
+ TestStart();
+ r = FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("File system caching failed - Skipping all file caching tests...\n"));
+ goto skipFileCacheTests;
+ }
+
+ GetAllPageInfo();
+ index = 0;
+ while (index < gZoneCount && gZoneUtilArray[index].iAllocDiscardable < KDisPagesReq)
+ {
+ ++ index;
+ }
+
+ if (index == gZoneCount)
+ {
+ test.Printf(_L("Cannot find zone to perform test on - Skipping test step...\n"));
+ }
+ else
+ {
+ zoneID = gZoneConfigArray[index].iZoneId;
+
+ allocSize = 14;
+
+ TESTDEBUG(test.Printf(_L("Filling the remaining free pages with fixed pages.....\n")));
+ Ldd.AllocateFixed(gTotalPageCount.iFreePages);
+
+ test.Printf(_L("Allocating 0x%x fixed pages to zone ID 0x%x.....\n"), allocSize, zoneID);
+ r = Ldd2.AllocateFixed(allocSize);
+
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+
+ GetAllPageInfo();
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Fail: Fixed pages have not been allocated, r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(Ldd2.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+ TESTDEBUG(test.Printf(_L("Freeing all Fixed Pages.....\n")));
+ Ldd2.FreeAllFixedPages();
+ }
+ TestEnd();
+
+ test.Next(_L("Test4: Filling the FS Cache and allocating less than 16 contiguous fixed pages"));
+ TestStart();
+
+ r = FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("File system caching failed - Skipping all file caching tests...\n"));
+ goto skipFileCacheTests;
+ }
+ allocSize = 14 << gPageShift;
+
+ TESTDEBUG(test.Printf(_L("Filling the remaining free pages with fixed pages.....\n")));
+ GetAllPageInfo();
+ // Allocate the fixed array before getting any page counts
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages)
+ {
+ r = Ldd.ZoneAllocToManyArray(index, gZoneUtilArray[index].iFreePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate fixed array Zone %d r = %d - Skipping...\n"), index, r);
+ goto SkipTest4;
+ }
+ }
+ }
+
+ // Now fill all zones with fixed pages, 1 zone at a time
+ // to avoid the discardable pages being disturbed
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages)
+ {
+ r = Ldd.ZoneAllocToMany2(index, gZoneUtilArray[index].iFreePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate %d fixed to Zone %d r = %d - Skipping...\n"),
+ gZoneUtilArray[index].iFreePages, index, r);
+ goto SkipTest4;
+ }
+ }
+ }
+
+ GetAllPageInfo();
+ test.Printf(_L("number of free pages = 0x%x\n"), gTotalPageCount.iFreePages);
+ if (gTotalPageCount.iFreePages ||
+ gTotalPageCount.iDiscardablePages <= (TUint)(allocSize >> gPageShift))
+ {
+ test.Printf(_L("Setup failed - Skipping...\n"));
+ goto SkipTest4;
+ }
+
+ test.Printf(_L("Allocating 0x%x fixed pages.....\n"), allocSize >> gPageShift);
+ r = Ldd2.AllocContiguous(allocSize);
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+
+ GetAllPageInfo();
+ if (r != KErrNone || !gTotalPageCount.iDiscardablePages)
+ {
+ test.Printf(_L("Fail: Fixed pages have not been allocated, r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(Ldd2.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+
+SkipTest4:
+ TESTDEBUG(test.Printf(_L("Freeing all Fixed Pages.....\n")));
+ Ldd2.FreeAllFixedPages();
+ TestEnd();
+
+ test.Next(_L("Test5: Filling the FS Cache and allocating more than 16 contiguous fixed pages"));
+ TestStart();
+ // TestEnd() will have reduced any cache pages to minimum so just get current
+ // count of discardable pages.
+ GetAllPageInfo();
+ minDiscardPages = gTotalPageCount.iDiscardablePages;
+
+ r = FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("File system caching failed - Skipping all file caching tests...\n"));
+ goto skipFileCacheTests;
+ }
+
+ allocSize = 18 << gPageShift;
+
+ TESTDEBUG(test.Printf(_L("Filling the remaining free pages with fixed pages.....\n")));
+ GetAllPageInfo();
+
+ // Allocate the fixed array before getting any page counts
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages)
+ {
+ r = Ldd.ZoneAllocToManyArray(index, gZoneUtilArray[index].iFreePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate fixed array Zone %d r = %d - Skipping...\n"), index, r);
+ goto SkipTest5;
+ }
+ }
+ }
+
+ // Now fill all zones with fixed pages, 1 zone at a time
+ // to avoid the discardable pages being disturbed
+ for (TUint index = 0; index < gZoneCount; index++)
+ {
+ GetAllPageInfo();
+ if (gZoneUtilArray[index].iFreePages)
+ {
+ r = Ldd.ZoneAllocToMany2(index, gZoneUtilArray[index].iFreePages);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Failed to allocate %d fixed to Zone %d r = %d - Skipping...\n"),
+ gZoneUtilArray[index].iFreePages, index, r);
+ goto SkipTest5;
+ }
+ }
+ }
+
+ GetAllPageInfo();
+ test.Printf(_L("number of free pages = 0x%x\n"), gTotalPageCount.iFreePages);
+ if (gTotalPageCount.iFreePages)
+ {
+ test.Printf(_L("Setup failed - Skipping...\n"));
+ goto SkipTest5;
+ }
+
+ test.Printf(_L("Allocating 0x%x fixed pages.....\n"), allocSize >> gPageShift);
+ r = Ldd2.AllocContiguous(allocSize);
+ TESTDEBUG(test.Printf(_L("r = %d\n"), r));
+
+ GetAllPageInfo();
+ if (r != KErrNone || gTotalPageCount.iDiscardablePages != minDiscardPages)
+ {
+ test.Printf(_L("Fail: r = %d, expected = %d - Discardable Pages = 0x%x, expected = %d\n"),
+ r, KErrNone, gTotalPageCount.iDiscardablePages, minDiscardPages);
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(Ldd2.FreeAllFixedPages());
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed...\n"));
+ }
+SkipTest5:
+
+skipFileCacheTests:
+ TestEnd();
+ TESTDEBUG(test.Printf(_L("Freeing all Fixed Pages.....\n")));
+ Ldd2.FreeAllFixedPages();
+ Ldd2.Close();
+ gTheFs.Close();
+ FormatMMC();
+ test.End();
+ return KErrNone;
+
+ }
+
+
+//
+// TestOneZoneConfig
+//
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-t_ramdefrag-0600
+//! @SYMTestType CIT
+//! @SYMTestCaseDesc Verifying that when only 1 zone is cofigured in the variant, that
+//! the defrag and allocation of fixed pages happend correctly
+//! @SYMPREQ PREQ308
+//! @SYMTestPriority High
+//! @SYMTestActions
+//! 1. Fragment the memory and perform a DefragRam
+//! 2. Fragment the memory and perform an EmptyZone
+//! 3. Fragment the memory and perform a ClaimZone
+//! 4. Call ZoneAllocPhysicalRam to allocate discontiguous fixed pages
+//! 5. Call ZoneAllocPhysicalRam to allocate contiguous fixed pages
+//!
+//! @SYMTestExpectedResults
+//! 1. Number of pages does not differ from the original
+//! 2. KErrNoMemroy and discardable pages are discarded of
+//! 3. KErrNoMemory
+//! 4. KErrNone
+//! 5. KErrNone
+//---------------------------------------------------------------------------------------------------------------------
+TInt TestOneZoneConfig()
+ {
+ TInt r = gTheFs.Connect();
+ test_KErrNone(r);
+
+ if (gDrive != KNoRemovableDrive)
+ {
+ SetUpMMC();
+ }
+
+ TUint index = 0;
+ GetAllPageInfo();
+ TUint zoneID = gZoneConfigArray[index].iZoneId;
+ test.Printf(_L("Zone ID = 0x%x\n"), zoneID);
+ TUint minCacheSize = 0;
+ TUint maxCacheSize = 0;
+ TUint currentCacheSize = 0;
+
+
+ TUint origFree = 0;
+ TUint origUnknown = 0;
+ TUint origFixed = 0;
+ TUint origMovable = 0;
+ TUint origDiscard = 0;
+ TUint origOther = 0;
+
+ if (gPagedRom)
+ {
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+
+ TUint setMin = 60 << gPageShift;
+ TInt setMax = -1;
+ TInt r = DPTest::SetCacheSize(setMin, setMax);
+ if (r != KErrNone)
+ {
+ test.Printf(_L("r = %d, expected = %d\n"), r, KErrNone);
+ CLEANUP(ResetDPCache());
+ TEST_FAIL;
+ }
+ DPTest::CacheSize(minCacheSize,maxCacheSize,currentCacheSize);
+ TESTDEBUG(test.Printf(_L("Original CacheSize: minCacheSize = 0x%x, maxCacheSize = 0x%x, currentCacheSize = 0x%x\n"),
+ minCacheSize >> gPageShift, maxCacheSize >> gPageShift, currentCacheSize >> gPageShift));
+ }
+
+ test.Start(_L("Test1: Fragmenting the memory and performing a general defrag"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ if (gDrive != KNoRemovableDrive)
+ {
+ FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ }
+ else
+ {
+ test.Printf(_L("Cannot find drive to write files to - Not allocating discardable pages through FS Caching\n"));
+ }
+
+ GetAllPageInfo();
+ origFree = gTotalPageCount.iFreePages;
+ origUnknown = gTotalPageCount.iUnknownPages;
+ origFixed = gTotalPageCount.iFixedPages;
+ origMovable = gTotalPageCount.iMovablePages;
+ origDiscard = gTotalPageCount.iDiscardablePages;
+ origOther = gTotalPageCount.iOtherPages;
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+ GetAllPageInfo();
+
+ if ((origUnknown != gTotalPageCount.iUnknownPages) ||
+ (origFixed != gTotalPageCount.iFixedPages) ||
+ (origMovable != gTotalPageCount.iMovablePages) ||
+ (origDiscard != gTotalPageCount.iDiscardablePages) ||
+ (origOther != gTotalPageCount.iOtherPages))
+ {
+ test.Printf(_L("Fail: Pages after defrag are not equal to those before"));
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+ // This will free any allocated memory
+ TestEnd();
+
+
+ test.Next(_L("Test2: Fragmenting the memory and performing an EmptyZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ if (gDrive != KNoRemovableDrive)
+ {
+ FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ }
+ else
+ {
+ test.Printf(_L("Cannot find drive to write files to - Not allocating discardable pages through FS Caching\n"));
+ }
+ r = Ldd.CallDefrag(DEFRAG_TYPE_EMPTY, DEFRAG_VER_SYNC, zoneID);
+
+ if (r != KErrNoMemory || CheckZoneIsOff(index))
+ {
+ test.Printf(_L("Fail: r = %d, expected = -4"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+ // This will free any allocated memory
+ TestEnd();
+
+ test.Next(_L("Test3: Fragmenting the memory and performing a ClaimZone"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ if (gDrive != KNoRemovableDrive)
+ {
+ FillCache(gFilesNeededToFillCache, KDefaultCacheSize);
+ }
+ else
+ {
+ test.Printf(_L("Cannot find drive to write files to - Not allocating discardable pages through FS Caching\n"));
+ }
+
+ GetAllPageInfo();
+ origMovable = gTotalPageCount.iMovablePages;
+
+ r = Ldd.CallDefrag(DEFRAG_TYPE_CLAIM, DEFRAG_VER_SYNC, zoneID);
+
+ GetAllPageInfo();
+ if (r != KErrNoMemory || origMovable != gTotalPageCount.iMovablePages)
+ {
+ test.Printf(_L("Fail: r = %d, expected = -4"), r);
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+ // This will free any allocated memory.
+ TestEnd();
+
+ test.Next(_L("Test4: Calling ZoneAllocPhysicalRam to allocate discontiguous fixed pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ origFree = gTotalPageCount.iFreePages;
+ origUnknown = gTotalPageCount.iUnknownPages;
+ origFixed = gTotalPageCount.iFixedPages;
+ origMovable = gTotalPageCount.iMovablePages;
+ origDiscard = gTotalPageCount.iDiscardablePages;
+ origOther = gTotalPageCount.iOtherPages;
+
+ r = Ldd.ZoneAllocDiscontiguous(zoneID, (TInt)(origFree / 2));
+
+ GetAllPageInfo();
+ if (gTotalPageCount.iFixedPages < (origFixed + (origFree / 2)))
+ {
+ test.Printf(_L("Fail: fixed pages = 0x%x, expected >= 0x%x\n"),
+ gTotalPageCount.iFixedPages, (origFixed + (origFree / 2)));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+ Ldd.FreeAllFixedPages();
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+
+ test.Next(_L("Test5: Calling ZoneAllocPhysicalRam to allocate contiguous fixed pages"));
+ TestStart();
+
+ AllocMovable(gChunkArray1, gChunkArraySize1, KNumAllocChunks);
+ FreeMovable(gChunkArray1, gChunkArraySize1);
+
+ GetAllPageInfo();
+ origFree = gTotalPageCount.iFreePages;
+ origUnknown = gTotalPageCount.iUnknownPages;
+ origFixed = gTotalPageCount.iFixedPages;
+ origMovable = gTotalPageCount.iMovablePages;
+ origDiscard = gTotalPageCount.iDiscardablePages;
+ origOther = gTotalPageCount.iOtherPages;
+
+ TInt allocSize = 50 << gPageShift;
+
+ r = Ldd.ZoneAllocContiguous(zoneID, allocSize);
+
+ GetAllPageInfo();
+ if (gTotalPageCount.iFixedPages < (origFixed + (allocSize >> gPageShift)))
+ {
+ test.Printf(_L("Fail: fixed pages = 0x%x, expected >= 0x%x\n"),
+ gTotalPageCount.iFixedPages, (origFixed + (allocSize >> gPageShift)));
+ CLEANUP(Ldd.FreeAllFixedPages());
+ CLEANUP(RemoveChunkAlloc(gChunkArray1, gChunkArraySize1));
+ TEST_FAIL;
+ }
+ else
+ {
+ test.Printf(_L("Passed..."));
+ }
+ Ldd.FreeAllFixedPages();
+ RemoveChunkAlloc(gChunkArray1, gChunkArraySize1);
+ TestEnd();
+
+ if (gPagedRom)
+ {
+ test_KErrNone(DPTest::FlushCache());
+ ResetDPCache();
+ }
+
+ gTheFs.Close();
+ if (gDrive != KNoRemovableDrive)
+ {
+ FormatMMC();
+ }
+
+ test.End();
+ return KErrNone;
+ }
+
+
+//
+// RunDefragTests
+//
+// List of defrag tests to be run
+//
+void RunDefragTests()
+ {
+ test.Start(_L("Testing the moving of pages in a defrag"));
+ TestMovPgsDefrag();
+
+ test.Next(_L("Verifying the implementation of the function TRamDefragRequest::DefragRam() arg aMaxPages"));
+ TestDefragRamMaxPages();
+
+ test.Next(_L("Verifying the implementation of the function TRamDefragRequest::EmptyRamZone()"));
+ TestEmptyRamZone();
+
+ test.Next(_L("Verifying the implementation of the function Epoc::GetRamZonePageCount()"));
+ TestGetRamZonePageCount();
+
+ test.Next(_L("Verifying the implementation of the function TRamDefragRequest::ClaimRamZone()"));
+ TestClaimRamZone();
+
+ test.Next(_L("Verifying the implementation of the function TRamDefragRequest::Cancel()"));
+ TestCancelDefrag();
+
+ test.Next(_L("Verifying that pages are moved correctly"));
+ TestMovingPages();
+
+ test.Next(_L("Verifying Semaphore Methods of the Defrag"));
+ TestDefragSemMethod();
+
+ test.Next(_L("Verifying Dfc Methods of the Defrag"));
+ TestDefragDfcMethod();
+
+ test.Next(_L("Testing priorities"));
+ TestPriorities();
+
+ test.Next(_L("Testing File System Caching"));
+ if (!gPagedRom)
+ {
+ TestFileCaching();
+ }
+ else
+ {
+ test.Printf(_L("Skipping... \n"));
+ }
+
+ test.Next(_L("Testing general RAM defrag implementation"));
+ TestGenDefrag();
+
+ test.End();
+ }
+
+
+//
+// RunAllocTests
+//
+// List of allocating tests to be run
+// These tests only need to be executed once
+//
+void RunAllocTests()
+ {
+ test.Start(_L("Verifying the allocating strategies"));
+ TestAllocStrategies();
+
+ test.Next(_L("Verifying the contiguous overload of Epoc::ZoneAllocPhysicalRam()"));
+ TestZoneAllocContiguous();
+
+ test.Next(_L("Verifying the discontiguous overload of Epoc::ZoneAllocPhysicalRam()"));
+ TestZoneAllocDiscontiguous();
+
+ test.Next(_L("Test Free Zone"));
+ TestFreeZone();
+
+ test.Next(_L("Testing zone flags"));
+ TestFlags();
+
+ test.End();
+ }
+
+
+//
+// E32Main
+//
+// Main entry point.
+//
+TInt E32Main()
+ {
+ test.Title();
+ DeviceDriver(TEST_DRIVER_OPEN);
+ gTotalRamLost = 0;
+
+ TInt r = TestSetup();
+ if (r != KErrNone)
+ {
+ test.Printf(_L("Test Setup failed, r = %d\n"), r);
+ TestCleanup();
+ return r;
+ }
+
+ if (gZoneCount == 1)
+ {
+ GetAllPageInfo();
+
+ test.Start(_L("Zone Count 1..."));
+ TestOneZoneConfig();
+ }
+ else
+ {
+ test.Start(_L("Running Alloc tests"));
+ RunAllocTests();
+
+ Ldd.ResetDriver();
+ Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+
+
+ test.Next(_L("Running Defrag tests"));
+ RunDefragTests();
+
+ Ldd.ResetDriver();
+ Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC);
+ }
+
+
+ test.Printf(_L("The total number of test steps failed = %d\n"), gTestStepFailed);
+ test_Equal(KErrNone, gTestStepFailed);
+
+ TestCleanup();
+
+ DeviceDriver(TEST_DRIVER_CLOSE);
+ test.End();
+ test.Close();
+
+ return 0;
+ }