kerneltest/e32test/defrag/d_ramdefrag.cpp
changeset 0 a41df078684a
child 102 ef2a444a7410
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\defrag\d_testramdefrag.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 //#define DEBUG_VER				// Uncomment for tracing
       
    19 
       
    20 #include "platform.h"
       
    21 #include <kernel/kern_priv.h>
       
    22 #include <kernel/cache.h>
       
    23 #include "t_ramdefrag.h"
       
    24 
       
    25 //
       
    26 // Class definitions
       
    27 //
       
    28 const TInt KMajorVersionNumber=0;
       
    29 const TInt KMinorVersionNumber=1;
       
    30 const TInt KBuildVersionNumber=1;
       
    31 
       
    32 
       
    33 const TInt KDefragCompleteThreadPriority = 27;
       
    34 _LIT(KDefragCompleteThread,"DefragCompleteThread");
       
    35 
       
    36 class DRamDefragFuncTestFactory : public DLogicalDevice
       
    37 	{
       
    38 public:
       
    39 
       
    40 	DRamDefragFuncTestFactory();
       
    41 	~DRamDefragFuncTestFactory();
       
    42 	virtual TInt Install();
       
    43 	virtual void GetCaps(TDes8& aDes) const;
       
    44 	virtual TInt Create(DLogicalChannelBase*& aChannel);
       
    45 
       
    46 	TDynamicDfcQue* iDfcQ;
       
    47 	};
       
    48 
       
    49 class DRamDefragFuncTestChannel : public DLogicalChannelBase
       
    50 	{
       
    51 public:
       
    52 	DRamDefragFuncTestChannel(TDfcQue* aDfcQ);
       
    53 
       
    54 	DRamDefragFuncTestChannel();
       
    55 	~DRamDefragFuncTestChannel();
       
    56 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
    57 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
       
    58 
       
    59 	TInt FreeAllFixedPages();
       
    60 	TInt AllocFixedPages(TInt aNumPages);
       
    61 	TInt AllocFixedArray(TInt aNumPages);
       
    62 	TInt AllocateFixed2(TInt aNumPages);
       
    63 	TInt GetAllocDiff(TUint aNumPages);
       
    64 	TInt FreeAllFixedPagesRead();
       
    65 	TInt AllocFixedPagesWrite(TInt aNumPages);
       
    66 	TInt ZoneAllocContiguous(TUint aZoneID, TUint aNumBytes);
       
    67 	TInt ZoneAllocContiguous(TUint* aZoneIdList, TUint aZoneIdCount, TUint aNumBytes);
       
    68 	TInt ZoneAllocDiscontiguous(TUint aZoneID, TInt aNumPages);
       
    69 	TInt ZoneAllocDiscontiguous(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages);
       
    70 	TInt ZoneAllocToMany(TInt aZoneIndex, TInt aNumPages);
       
    71 	TInt ZoneAllocToManyArray(TInt aZoneIndex, TInt aNumPages);
       
    72 	TInt ZoneAllocToMany2(TInt aZoneIndex, TInt aNumPages);
       
    73 	TInt AllocContiguous(TUint aNumBytes);
       
    74 	TInt FreeZone(TInt aNumPages);
       
    75 	TInt FreeFromAllZones();
       
    76 	TInt FreeFromAddr(TInt aNumPages, TUint32 aAddr);
       
    77 	TInt PageCount(TUint aId, STestUserSidePageCount* aPageData);
       
    78 	TInt CancelDefrag();
       
    79 	TInt CheckCancel(STestParameters* aParams);
       
    80 	TInt CallDefrag(STestParameters* aParams);
       
    81 	TInt CheckPriorities(STestParameters* aParams);
       
    82 	TInt SetZoneFlag(STestFlagParams* aParams);
       
    83 	TInt GetDefragOrder();
       
    84 	TInt FreeRam();
       
    85 	TInt DoSetDebugFlag(TInt aState);
       
    86 	TInt ResetDriver();
       
    87 	TInt ZoneAllocDiscontiguous2(TUint aZoneID, TInt aNumPages);
       
    88 public:
       
    89 	DRamDefragFuncTestFactory*	iFactory;
       
    90 
       
    91 protected:
       
    92 	static void DefragCompleteDfc(TAny* aSelf);
       
    93 	void DefragComplete();
       
    94 		static void Defrag2CompleteDfc(TAny* aSelf);
       
    95 	void Defrag2Complete();
       
    96 		static void Defrag3CompleteDfc(TAny* aSelf);
       
    97 	void Defrag3Complete();
       
    98 private:
       
    99 	TPhysAddr				iContigAddr;		/**< The base address of fixed contiguous allocations*/
       
   100 	TUint					iContigBytes;		/**< The no. of contiguous fixed bytes allocated*/
       
   101 	TPhysAddr*				iAddrArray;	
       
   102 	TUint					iAddrArrayPages;
       
   103 	TUint					iAddrArraySize;
       
   104 	TPhysAddr**				iAddrPtrArray;			
       
   105 	TInt*					iNumPagesArray;
       
   106 	TInt					iDebug;
       
   107 	TInt					iThreadCounter;
       
   108 	DChunk*					iChunk;
       
   109 	TLinAddr				iKernAddrStart;
       
   110 	TInt					iPageSize;
       
   111 	TUint 					iPageShift;			/**< The system's page shift */
       
   112 	TUint					iZoneCount;
       
   113 	TRamDefragRequest		iDefragRequest;		//	Defrag request object
       
   114 	TRamDefragRequest		iDefragRequest2;
       
   115 	TRamDefragRequest		iDefragRequest3;
       
   116 	TUint*					iZoneIdArray;		/**< Pointer to an kernel heap array of zone IDs*/
       
   117 
       
   118 
       
   119 	DSemaphore*				iDefragSemaphore;	//	Semaphore enusre only one defrag operation is active per channel
       
   120 	TRequestStatus*			iCompleteReq;		//	Pointer to a request status that will signal to the user side client once the defrag has completed
       
   121 	TRequestStatus*			iCompleteReq2;
       
   122 	TRequestStatus*			iCompleteReq3;		
       
   123 	TRequestStatus			iTmpRequestStatus1;	
       
   124 	TRequestStatus			iTmpRequestStatus2;
       
   125 	DThread*				iRequestThread;		//	Pointer to the thread that made the defrag request
       
   126 	DThread*				iRequestThread2;
       
   127 	DThread*				iRequestThread3;		
       
   128 
       
   129 	TDfcQue*				iDfcQ;				//	The DFC queue used for driver functions 
       
   130 	TDfc					iDefragCompleteDfc;	//	DFC to be queued once a defrag operation has completed 
       
   131 	TDfc					iDefragComplete2Dfc;
       
   132 	TDfc					iDefragComplete3Dfc;
       
   133 	TInt					iCounter;			//	Counts the number of defrags that have taken place
       
   134 	TInt					iOrder;				//	Stores the order in which queued defrags took place
       
   135 	};
       
   136 
       
   137 
       
   138 
       
   139 //
       
   140 // DRamDefragFuncTestFactory
       
   141 //
       
   142 
       
   143 DRamDefragFuncTestFactory::DRamDefragFuncTestFactory()
       
   144 //
       
   145 // Constructor
       
   146 //
       
   147     {
       
   148     iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
       
   149     //iParseMask=0;//No units, no info, no PDD
       
   150     //iUnitsMask=0;//Only one thing
       
   151     }
       
   152     
       
   153 TInt DRamDefragFuncTestFactory::Install()
       
   154 	{
       
   155 	return SetName(&KRamDefragFuncTestLddName);
       
   156 	}
       
   157 
       
   158 DRamDefragFuncTestFactory::~DRamDefragFuncTestFactory()
       
   159 	{
       
   160 	if (iDfcQ != NULL)
       
   161 		{// Destroy the DFC queue created when this device drvier was loaded.
       
   162 		iDfcQ->Destroy();
       
   163 		}
       
   164 	}
       
   165 
       
   166 void DRamDefragFuncTestFactory::GetCaps(TDes8& /*aDes*/) const
       
   167 	{
       
   168 	// Not used but required as DLogicalDevice::GetCaps is pure virtual
       
   169 	}
       
   170 
       
   171 TInt DRamDefragFuncTestFactory::Create(DLogicalChannelBase*& aChannel)
       
   172 	{
       
   173 	DRamDefragFuncTestChannel* channel=new DRamDefragFuncTestChannel(iDfcQ);
       
   174 	if(!channel)
       
   175 		return KErrNoMemory;
       
   176 	channel->iFactory = this;
       
   177 	aChannel = channel;
       
   178 	return KErrNone;
       
   179 	}
       
   180 
       
   181 DECLARE_STANDARD_LDD()
       
   182 	{
       
   183 	DRamDefragFuncTestFactory* factory = new DRamDefragFuncTestFactory;
       
   184 	if (factory)
       
   185 		{
       
   186 		// Allocate a kernel thread to run the DFC 
       
   187 		TInt r = Kern::DynamicDfcQCreate(factory->iDfcQ, KDefragCompleteThreadPriority, KDefragCompleteThread);
       
   188 
       
   189 		if (r != KErrNone)
       
   190 			{// Must close rather than delete factory as it is a DObject object.
       
   191 			factory->AsyncClose();
       
   192 			return NULL; 	
       
   193 			} 	
       
   194 		}
       
   195     return factory;
       
   196 	}
       
   197 
       
   198 //
       
   199 // DRamDefragFuncTestChannel
       
   200 //
       
   201 
       
   202 TInt DRamDefragFuncTestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
       
   203 	{
       
   204 
       
   205 	TInt ret = Kern::HalFunction(EHalGroupRam, ERamHalGetZoneCount, (TAny*)&iZoneCount, NULL);
       
   206 
       
   207 
       
   208 	// Retrieve the page size and use it to detemine the page shift (assumes 32-bit system).
       
   209 	TInt r = Kern::HalFunction(EHalGroupKernel, EKernelHalPageSizeInBytes, &iPageSize, 0);
       
   210 	if (r != KErrNone)
       
   211 		{
       
   212 		TESTDEBUG(Kern::Printf("ERROR - Unable to determine page size"));
       
   213 		return r;
       
   214 		}
       
   215 	TUint32 pageMask = iPageSize;
       
   216 	TUint i = 0;
       
   217 	for (; i < 32; i++)
       
   218 		{
       
   219 		if (pageMask & 1)
       
   220 			{
       
   221 			if (pageMask & ~1u)
       
   222 				{
       
   223 				TESTDEBUG(Kern::Printf("ERROR - page size not a power of 2"));
       
   224 				return KErrNotSupported;
       
   225 				}
       
   226 			iPageShift = i;
       
   227 			break;
       
   228 			}
       
   229 		pageMask >>= 1;
       
   230 		}
       
   231 
       
   232 	// Create a semaphore to protect defrag invocation.  OK to just use one name as
       
   233 	// the semaphore is not global so it's name doesn't need to be unique.
       
   234 	ret = Kern::SemaphoreCreate(iDefragSemaphore, _L("DefragRefSem"), 1);
       
   235 	if (ret != KErrNone)
       
   236 		{
       
   237 		return ret;
       
   238 		}
       
   239 	iDefragCompleteDfc.SetDfcQ(iDfcQ);
       
   240 	iDefragComplete2Dfc.SetDfcQ(iDfcQ);
       
   241 	iDefragComplete3Dfc.SetDfcQ(iDfcQ);
       
   242 
       
   243 	// Create an array to store some RAM zone IDs for use but the multi-zone 
       
   244 	// specific allcoation methods.
       
   245 	NKern::ThreadEnterCS();
       
   246 	iZoneIdArray = new TUint[KMaxRamZones];
       
   247 	if (iZoneIdArray == NULL)
       
   248 		{
       
   249 		ret = KErrNoMemory;
       
   250 		}
       
   251 	NKern::ThreadLeaveCS();
       
   252 
       
   253 	return ret;
       
   254 	}
       
   255 
       
   256 DRamDefragFuncTestChannel::DRamDefragFuncTestChannel(TDfcQue* aDfcQ)
       
   257 	: 
       
   258 	iContigAddr(KPhysAddrInvalid),
       
   259 	iContigBytes(0),
       
   260 	iAddrArray(NULL), 
       
   261 	iAddrArrayPages(0),
       
   262 	iAddrArraySize(0),
       
   263 	iAddrPtrArray(NULL),
       
   264 	iNumPagesArray(NULL),
       
   265 	iDebug(0), 
       
   266 	iThreadCounter(1),
       
   267 	iChunk(NULL),
       
   268 	iPageSize(0), 
       
   269 	iPageShift(0),
       
   270 	iZoneCount(0),
       
   271 	iZoneIdArray(NULL),
       
   272 	iDefragSemaphore(NULL),
       
   273 	iCompleteReq(NULL),
       
   274 	iCompleteReq2(NULL),
       
   275 	iCompleteReq3(NULL),
       
   276 	iRequestThread(NULL),
       
   277 	iRequestThread2(NULL),
       
   278 	iRequestThread3(NULL),
       
   279 	iDfcQ(aDfcQ),
       
   280 	iDefragCompleteDfc(DefragCompleteDfc, (TAny*)this, 1),
       
   281 	iDefragComplete2Dfc(Defrag2CompleteDfc, (TAny*)this, 1), 
       
   282 	iDefragComplete3Dfc(Defrag3CompleteDfc, (TAny*)this, 1), 
       
   283 	iCounter(0), 
       
   284 	iOrder(0)
       
   285 	{
       
   286 	}
       
   287 
       
   288 DRamDefragFuncTestChannel::~DRamDefragFuncTestChannel()
       
   289 	{
       
   290 	if (iDefragSemaphore != NULL)
       
   291 		{
       
   292 		iDefragSemaphore->Close(NULL);
       
   293 		}
       
   294 	if (iZoneIdArray != NULL)
       
   295 		{
       
   296 		NKern::ThreadEnterCS();
       
   297 		delete[] iZoneIdArray;
       
   298 		NKern::ThreadLeaveCS();
       
   299 		}
       
   300 	}
       
   301 
       
   302 TInt DRamDefragFuncTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
       
   303 	{
       
   304 	TInt threadCount = __e32_atomic_tas_ord32(&iThreadCounter, 1, 1, 0);
       
   305 	if (threadCount >= 2)
       
   306 		{
       
   307 		Kern::Printf("DRamDefragFuncTestChannel::Request threadCount = %d\n", threadCount);
       
   308 		}
       
   309 
       
   310 	Kern::SemaphoreWait(*iDefragSemaphore);
       
   311 
       
   312 
       
   313 	TInt retVal = KErrNotSupported;
       
   314 	switch(aFunction)
       
   315 		{
       
   316 		case RRamDefragFuncTestLdd::EAllocateFixed:
       
   317 			retVal = DRamDefragFuncTestChannel::AllocFixedPages((TInt)a1);
       
   318 			break;
       
   319 			
       
   320 		case RRamDefragFuncTestLdd::EAllocFixedArray:
       
   321 			retVal = DRamDefragFuncTestChannel::AllocFixedArray((TInt)a1);
       
   322 			break;
       
   323 						
       
   324 		case RRamDefragFuncTestLdd::EAllocateFixed2:
       
   325 			retVal = DRamDefragFuncTestChannel::AllocateFixed2((TInt)a1);
       
   326 			break;
       
   327 		
       
   328 		case RRamDefragFuncTestLdd::EGetAllocDiff:
       
   329 			retVal = DRamDefragFuncTestChannel::GetAllocDiff((TUint)a1);
       
   330 			break;
       
   331 
       
   332 		case RRamDefragFuncTestLdd::EFreeAllFixed:
       
   333 			retVal = DRamDefragFuncTestChannel::FreeAllFixedPages();
       
   334 			break;
       
   335 
       
   336 		case RRamDefragFuncTestLdd::EAllocateFixedWrite:
       
   337 			retVal = DRamDefragFuncTestChannel::AllocFixedPagesWrite((TInt)a1);
       
   338 			break;
       
   339 		
       
   340 		case RRamDefragFuncTestLdd::EFreeAllFixedRead:
       
   341 			retVal = DRamDefragFuncTestChannel::FreeAllFixedPagesRead();
       
   342 			break;
       
   343 		
       
   344 		case RRamDefragFuncTestLdd::EZoneAllocContiguous:
       
   345 			retVal = DRamDefragFuncTestChannel::ZoneAllocContiguous((TUint)a1, (TUint)a2);
       
   346 			break;
       
   347 
       
   348 		case RRamDefragFuncTestLdd::EMultiZoneAllocContiguous:
       
   349 			{
       
   350 			SMultiZoneAlloc multiZone;
       
   351 			kumemget(&multiZone, a1, sizeof(SMultiZoneAlloc));
       
   352 			retVal = DRamDefragFuncTestChannel::ZoneAllocContiguous(multiZone.iZoneId, multiZone.iZoneIdSize, (TUint)a2);
       
   353 			}
       
   354 			break;
       
   355 
       
   356 		case RRamDefragFuncTestLdd::EZoneAllocDiscontiguous:
       
   357 			retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous((TUint)a1, (TUint)a2);	
       
   358 			break;
       
   359 
       
   360 		case RRamDefragFuncTestLdd::EMultiZoneAllocDiscontiguous:
       
   361 			{
       
   362 			SMultiZoneAlloc multiZone;
       
   363 			kumemget(&multiZone, a1, sizeof(SMultiZoneAlloc));
       
   364 			retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(multiZone.iZoneId, multiZone.iZoneIdSize, (TUint)a2);	
       
   365 			}
       
   366 			break;
       
   367 
       
   368 		case RRamDefragFuncTestLdd::EZoneAllocDiscontiguous2:
       
   369 			retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous2((TUint)a1, (TUint)a2);	
       
   370 			break;
       
   371 
       
   372 		case RRamDefragFuncTestLdd::EZoneAllocToMany:
       
   373 			retVal = DRamDefragFuncTestChannel::ZoneAllocToMany((TUint)a1, (TInt)a2);	
       
   374 			break;
       
   375 
       
   376 		case RRamDefragFuncTestLdd::EZoneAllocToManyArray:
       
   377 			retVal = DRamDefragFuncTestChannel::ZoneAllocToManyArray((TUint)a1, (TInt)a2);	
       
   378 			break;
       
   379 
       
   380 		case RRamDefragFuncTestLdd::EZoneAllocToMany2:
       
   381 			retVal = DRamDefragFuncTestChannel::ZoneAllocToMany2((TUint)a1, (TInt)a2);	
       
   382 			break;
       
   383 
       
   384 		case RRamDefragFuncTestLdd::EAllocContiguous:
       
   385 			retVal = DRamDefragFuncTestChannel::AllocContiguous((TUint)a1);	
       
   386 			break;
       
   387 
       
   388 		case RRamDefragFuncTestLdd::EFreeZone:
       
   389 			retVal = DRamDefragFuncTestChannel::FreeZone((TInt)a1);
       
   390 			break;
       
   391 
       
   392 		case RRamDefragFuncTestLdd::EFreeFromAllZones:
       
   393 			retVal = DRamDefragFuncTestChannel::FreeFromAllZones();	
       
   394 			break;
       
   395 		
       
   396 		case RRamDefragFuncTestLdd::EFreeFromAddr:
       
   397 			retVal = DRamDefragFuncTestChannel::FreeFromAddr((TInt)a1, (TUint32)a2);	
       
   398 			break;
       
   399 			
       
   400 		case RRamDefragFuncTestLdd::EPageCount:
       
   401 			retVal = DRamDefragFuncTestChannel::PageCount((TUint)a1, (STestUserSidePageCount*)a2);	
       
   402 			break;
       
   403 		
       
   404 		case RRamDefragFuncTestLdd::ECheckCancel:
       
   405 			retVal = DRamDefragFuncTestChannel::CheckCancel((STestParameters*)a1);	
       
   406 			break;
       
   407 
       
   408 		case RRamDefragFuncTestLdd::ECallDefrag:
       
   409 			retVal = DRamDefragFuncTestChannel::CallDefrag((STestParameters*)a1);	
       
   410 			break;
       
   411 
       
   412 		case RRamDefragFuncTestLdd::ESetZoneFlag:
       
   413 			retVal = DRamDefragFuncTestChannel::SetZoneFlag((STestFlagParams*)a1);	
       
   414 			break;
       
   415 
       
   416 		case RRamDefragFuncTestLdd::ECheckPriorities:
       
   417 			retVal = DRamDefragFuncTestChannel::CheckPriorities((STestParameters*)a1);	
       
   418 			break;
       
   419 
       
   420 		case RRamDefragFuncTestLdd::EGetDefragOrder:
       
   421 			retVal = DRamDefragFuncTestChannel::GetDefragOrder();	
       
   422 			break;
       
   423 
       
   424 		case RRamDefragFuncTestLdd::EDoSetDebugFlag:
       
   425 			retVal = DoSetDebugFlag((TInt) a1);
       
   426 			break;
       
   427 		
       
   428 		case RRamDefragFuncTestLdd::EResetDriver:
       
   429 			retVal = ResetDriver();
       
   430 			break;
       
   431 
       
   432 		default: 
       
   433 			break;
       
   434 		}
       
   435 
       
   436 	Kern::SemaphoreSignal(*iDefragSemaphore);
       
   437 	__e32_atomic_tas_ord32(&iThreadCounter, 1, -1, 0);
       
   438 	return retVal;
       
   439 	}
       
   440 
       
   441 
       
   442 #define CHECK(c) { if(!(c)) { Kern::Printf("Fail  %d", __LINE__); ; retVal = __LINE__;} }
       
   443 
       
   444 
       
   445 //
       
   446 // FreeAllFixedPages
       
   447 //
       
   448 // Free ALL of the fixed pages that were allocated
       
   449 //
       
   450 TInt DRamDefragFuncTestChannel::FreeAllFixedPages()
       
   451 	{
       
   452 	NKern::ThreadEnterCS();
       
   453 
       
   454 	TInt retVal = KErrNone;
       
   455 
       
   456 	if (iAddrArray != NULL)
       
   457 		{
       
   458 		retVal = Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
       
   459 		CHECK(retVal == KErrNone);
       
   460 
       
   461 		delete[] iAddrArray;
       
   462 		iAddrArray = NULL;
       
   463 		iAddrArrayPages = 0;
       
   464 		}
       
   465 	
       
   466 	if (iContigAddr != KPhysAddrInvalid)
       
   467 		{
       
   468 		retVal = Epoc::FreePhysicalRam(iContigAddr, iContigBytes);
       
   469 		iContigAddr = KPhysAddrInvalid;
       
   470 		iContigBytes = 0;
       
   471 		CHECK(retVal == KErrNone);
       
   472 		}
       
   473 	NKern::ThreadLeaveCS();
       
   474 
       
   475 	retVal = FreeFromAllZones();
       
   476 	return retVal;
       
   477 	}
       
   478 
       
   479 
       
   480 
       
   481 //
       
   482 // FreeAllFixedPagesRead()
       
   483 //
       
   484 // Read the fixed pages that were mapped to iChunk and verify that 
       
   485 // the contents have not changed.  Then free the fixed pages 
       
   486 // that were allocated for iChunk.
       
   487 //
       
   488 TInt DRamDefragFuncTestChannel::FreeAllFixedPagesRead()
       
   489 	{
       
   490 
       
   491 	TInt retVal = KErrNone;
       
   492 	TUint index;
       
   493 	
       
   494 	if (iAddrArray == NULL || iChunk == NULL || !iAddrArrayPages)
       
   495 		{
       
   496 		return KErrCorrupt;
       
   497 		}
       
   498 	
       
   499 	TInt r = Kern::ChunkAddress(iChunk, 0, iAddrArrayPages << iPageShift, iKernAddrStart);
       
   500 	if (r != KErrNone)
       
   501 		{
       
   502 		Kern::Printf("ERROR ? FreeAllFixedPages : Couldn't get linear address of iChunk! %d", r);
       
   503 		}
       
   504 	else
       
   505 		{
       
   506 		for (index = 0; index < iAddrArrayPages; index ++)
       
   507 			{
       
   508 			if (iAddrArray[index] != NULL)
       
   509 				{
       
   510 				TUint* pInt = (TUint *)(iKernAddrStart + (index << iPageShift));
       
   511 				TUint* pIntEnd = pInt + (iPageSize / sizeof(TInt));
       
   512 				// Read each word in this the page and verify that 
       
   513 				// they are still the index of the current page in the chunk.
       
   514 				while (pInt < pIntEnd)
       
   515 					{
       
   516 					if (*pInt++ != index)
       
   517 						{
       
   518 						Kern::Printf("ERROR ? FreeAllFixedPages : page at index %d is corrupt! 0x%08x", index, *pInt);
       
   519 						}
       
   520 					}
       
   521 				}
       
   522 			}
       
   523 		}
       
   524 	NKern::ThreadEnterCS();
       
   525 
       
   526 	// Must close chunk before we free memory otherwise it would still be 
       
   527 	// possible to access memory that has been freed and potentially reused.
       
   528 	Kern::ChunkClose(iChunk);
       
   529 	iChunk = NULL;
       
   530 	retVal = Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
       
   531 	delete[] iAddrArray;
       
   532 
       
   533 	NKern::ThreadLeaveCS();
       
   534 
       
   535 	iAddrArray = NULL;
       
   536 	iAddrArrayPages = 0;
       
   537 	return retVal;
       
   538 	}
       
   539 
       
   540 //
       
   541 // AllocFixedPagesWrite
       
   542 //
       
   543 // Allocate a number of fixed pages to memory then create a shared chunk and map these pages into the chunk
       
   544 //
       
   545 TInt DRamDefragFuncTestChannel::AllocFixedPagesWrite(TInt aNumPages)
       
   546 	{
       
   547 
       
   548 	TInt retVal = KErrNone;
       
   549 	TUint index = 0;
       
   550 	TChunkCreateInfo 	chunkInfo;
       
   551 	TUint32 			mapAttr;
       
   552 
       
   553 	if (iAddrArray != NULL || iChunk != NULL)
       
   554 		{
       
   555 		return KErrInUse;
       
   556 		}
       
   557 
       
   558 	if (aNumPages == FILL_ALL_FIXED)
       
   559 		{// Fill memory with fixed pages, leaving room for the kernel to expand.
       
   560 		TUint freePages = FreeRam() >> iPageShift;
       
   561 		// Calculate how many page tables will be required:
       
   562 		// 	1024 pages per page table 
       
   563 		//	4 page table per page
       
   564 		TUint pageTablePages = (freePages >> 10) >> 2;
       
   565 		TUint physAddrPages = (sizeof(TPhysAddr) * freePages) >> iPageShift;
       
   566 		TESTDEBUG(Kern::Printf("pageTablePages %d physAddrPages %d", pageTablePages, physAddrPages));
       
   567 		// Determine how many heap pages will be required, with some extra space as well.
       
   568 		TUint fixedOverhead = (pageTablePages + physAddrPages) << 4;
       
   569 		TESTDEBUG(Kern::Printf("freePages %d fixedOverhead %d", freePages, fixedOverhead));
       
   570 		aNumPages = freePages - fixedOverhead;
       
   571 		TESTDEBUG(Kern::Printf("aNumPages = %d", aNumPages));
       
   572 		}
       
   573 
       
   574 	NKern::ThreadEnterCS();
       
   575 
       
   576 	iAddrArray = new TPhysAddr[aNumPages];
       
   577 	if(!iAddrArray)
       
   578 		{
       
   579 		retVal = KErrNoMemory;
       
   580 		goto exit;
       
   581 		}
       
   582 	
       
   583 	TESTDEBUG(Kern::Printf("amount of free pages = %d", FreeRam() >> iPageShift));	
       
   584 
       
   585 	// create a shared chunk and map these pages into the chunk.
       
   586 	
       
   587 	chunkInfo.iType			= TChunkCreateInfo::ESharedKernelSingle;
       
   588 	chunkInfo.iMaxSize		= aNumPages << iPageShift;
       
   589 	chunkInfo.iMapAttr		= EMapAttrFullyBlocking;
       
   590 	chunkInfo.iOwnsMemory	= EFalse;
       
   591 
       
   592 	TESTDEBUG(Kern::Printf("Creating chunk - amount of free pages = %d\n", FreeRam() >> iPageShift));
       
   593 	retVal = Kern::ChunkCreate(chunkInfo, iChunk, iKernAddrStart, mapAttr);
       
   594 	if (retVal != KErrNone)
       
   595 		{
       
   596 		Kern::Printf("ChunkCreate failed retVal = %d", retVal);
       
   597 		goto exit;
       
   598 		}
       
   599 
       
   600 	TESTDEBUG(Kern::Printf("Created chunk - amount of free pages = %d\n", FreeRam() >> iPageShift));
       
   601 
       
   602 	retVal = Epoc::AllocPhysicalRam(aNumPages, iAddrArray);
       
   603 	if (retVal != KErrNone)
       
   604 		{
       
   605 		TESTDEBUG(Kern::Printf("Alloc of %d pages was unsuccessful\n", aNumPages));
       
   606 		goto exit;
       
   607 		}
       
   608 	iAddrArrayPages = aNumPages;
       
   609 	TESTDEBUG(Kern::Printf("Committing chunk - amount of free pages = %d\n", FreeRam() >> iPageShift));
       
   610 	retVal = Kern::ChunkCommitPhysical(iChunk, 0, iAddrArrayPages << iPageShift, iAddrArray);
       
   611 	if (retVal != KErrNone)
       
   612 		{
       
   613 		Kern::Printf("Commit was bad retVal = %d", retVal);
       
   614 		goto exit;
       
   615 		}
       
   616 	TESTDEBUG(Kern::Printf("Committed chunk - amount of free pages = %d\n", FreeRam() >> iPageShift));
       
   617 	TESTDEBUG(Kern::Printf("Start - 0x%08x\n", iKernAddrStart));
       
   618 	for (index = 0; index < iAddrArrayPages; index ++)
       
   619 		{
       
   620 		TInt* pInt = (TInt *)(iKernAddrStart + (index << iPageShift));
       
   621 		TInt* pIntEnd = pInt + (iPageSize / sizeof(TInt));
       
   622 		// write the index into all of the words of the page.
       
   623 		while (pInt < pIntEnd)
       
   624 			{
       
   625 			*pInt++ = index;
       
   626 			}
       
   627 		}
       
   628 
       
   629 	TESTDEBUG(Kern::Printf("Allocated %d pages\n", iAddrArrayPages));
       
   630 exit:
       
   631 	if (retVal != KErrNone)
       
   632 		{// Cleanup as something went wrong
       
   633 		if (iChunk)
       
   634 			{
       
   635 			Kern::ChunkClose(iChunk);
       
   636 			iChunk = NULL;
       
   637 			}
       
   638 		if (iAddrArray != NULL)
       
   639 			{
       
   640 			Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
       
   641 			delete[] iAddrArray;
       
   642 			iAddrArray = NULL;
       
   643 			}
       
   644 		iAddrArrayPages = 0;
       
   645 		}
       
   646 
       
   647 	NKern::ThreadLeaveCS();
       
   648 	return retVal;
       
   649 	}
       
   650 
       
   651 TInt DRamDefragFuncTestChannel::GetAllocDiff(TUint aNumPages)
       
   652 	{
       
   653 	TUint initialFreeRam = FreeRam();
       
   654 	TInt ret = KErrNone;
       
   655 	TInt ramDifference;
       
   656 
       
   657 	NKern::ThreadEnterCS();
       
   658 
       
   659 	if (iAddrArray != NULL)
       
   660 		{
       
   661 		ret = KErrInUse;
       
   662 		goto exit;
       
   663 		}
       
   664 	iAddrArray = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * aNumPages);
       
   665 
       
   666 	if(!iAddrArray)
       
   667 		{
       
   668 		ret = KErrNoMemory;
       
   669 		goto exit;
       
   670 		}
       
   671 	
       
   672 	ramDifference = initialFreeRam - FreeRam();
       
   673 	
       
   674 	Kern::Free(iAddrArray);
       
   675 	iAddrArray = NULL;
       
   676 	
       
   677 	ret = ramDifference >> iPageShift;
       
   678 exit:
       
   679 	NKern::ThreadLeaveCS();
       
   680 	return ret;
       
   681 	}
       
   682 //
       
   683 // AllocFixedPages
       
   684 //
       
   685 // Allocate a number of fixed pages to memory
       
   686 //
       
   687 TInt DRamDefragFuncTestChannel::AllocFixedPages(TInt aNumPages)
       
   688 	{
       
   689 	TInt r = AllocFixedArray(aNumPages);
       
   690 	if (r != KErrNone)
       
   691 		{
       
   692 		return r;
       
   693 		}
       
   694 	return AllocateFixed2(aNumPages);
       
   695 	}
       
   696 
       
   697 /**
       
   698 Allocate the array required to store the physical addresses of 
       
   699 number of fixed pages to be allocated.
       
   700 
       
   701 @param aNumPages 	The number of fixed pages to be allocated.
       
   702 @return KErrNone on success.
       
   703 */
       
   704 TInt DRamDefragFuncTestChannel::AllocFixedArray(TInt aNumPages)
       
   705 	{	
       
   706 	if (iAddrArray != NULL)
       
   707 		{
       
   708 		return KErrInUse;
       
   709 		}
       
   710 	
       
   711 	if (aNumPages == FILL_ALL_FIXED)
       
   712 		{// Fill memory with fixed pages.
       
   713 		aNumPages = FreeRam() >> iPageShift;
       
   714 		TESTDEBUG(Kern::Printf("aNumPages %d FreeRam() %d", aNumPages, FreeRam()));
       
   715 		}
       
   716 	NKern::ThreadEnterCS();
       
   717 
       
   718 	iAddrArray = new TPhysAddr[aNumPages];
       
   719 	iAddrArraySize = aNumPages;	// Only required for AllocateFixed2() when aNumPages == FILL_ALL_FIXED.
       
   720 	iAddrArrayPages = 0;	// No physical pages have been allocated yet.
       
   721 
       
   722 	NKern::ThreadLeaveCS();
       
   723 
       
   724 	if (!iAddrArray)
       
   725 		{
       
   726 		return KErrNoMemory;
       
   727 		}
       
   728 	return KErrNone;
       
   729 	}
       
   730 
       
   731 
       
   732 /**
       
   733 Allocate the specified number of fixed pages.
       
   734 This should only be invoked when iAddrArray has already been allocated
       
   735 
       
   736 @param aNumPages 	The number of pages to allocate.
       
   737 */	
       
   738 TInt DRamDefragFuncTestChannel::AllocateFixed2(TInt aNumPages)
       
   739 	{
       
   740 	if (iAddrArray == NULL)
       
   741 		{
       
   742 		return KErrGeneral;
       
   743 		}
       
   744 	TInt retVal = KErrNone;
       
   745 	NKern::ThreadEnterCS();
       
   746 	if (aNumPages == FILL_ALL_FIXED)
       
   747 		{
       
   748 		// Allocate a number of fixed pages to RAM a page at time so that the allocations
       
   749 		// will always fill as much memory as possible.
       
   750 		TPhysAddr* addrPtr = iAddrArray;
       
   751 		TPhysAddr* addrPtrEnd = addrPtr + iAddrArraySize;
       
   752 		while (addrPtr < addrPtrEnd)
       
   753 			{
       
   754 			retVal = Epoc::AllocPhysicalRam(1, addrPtr++);
       
   755 			if (retVal != KErrNone)
       
   756 				break;
       
   757 			iAddrArrayPages++;
       
   758 			}
       
   759 		}
       
   760 	else
       
   761 		{
       
   762 		retVal = Epoc::AllocPhysicalRam(aNumPages, iAddrArray);
       
   763 		if (retVal != KErrNone)
       
   764 			{
       
   765 			TESTDEBUG(Kern::Printf("aNumPages %d FreeRam() %d", aNumPages, FreeRam()));
       
   766 			delete[] iAddrArray;
       
   767 			iAddrArray = NULL;
       
   768 			TESTDEBUG(Kern::Printf("aNumPages %d FreeRam() %d", aNumPages, FreeRam()));
       
   769 			TESTDEBUG(Kern::Printf("Fixed pages alloc was unsuccessful\n"));
       
   770 			}
       
   771 		else
       
   772 			iAddrArrayPages = aNumPages;
       
   773 		}
       
   774 
       
   775 	NKern::ThreadLeaveCS();
       
   776 	return retVal;
       
   777 	}	
       
   778 //
       
   779 // CheckCancel
       
   780 //
       
   781 // Check that when a defrag is cancelled, the correct return value is reported
       
   782 //
       
   783 TInt DRamDefragFuncTestChannel::CheckCancel(STestParameters* aParams)
       
   784 	{
       
   785 	TInt returnValue = KErrNone;
       
   786 	STestParameters params;
       
   787 	kumemget(&params, aParams, sizeof(STestParameters));
       
   788 
       
   789 	Kern::Printf(	"defragtype = %d, defragversion = %d, priority = %d, maxpages = %d, ID = %d", 
       
   790 					params.iDefragType, params.iDefragVersion, params.iPriority, params.iMaxPages, params.iID);
       
   791 
       
   792 
       
   793 	NFastSemaphore sem;
       
   794 	NKern::FSSetOwner(&sem, 0);
       
   795 	TPhysAddr zoneAddress;
       
   796 	TInt maxPages = 0;
       
   797 	TInt priority = (NKern::CurrentThread()->iPriority) - 2;
       
   798 
       
   799 	if (params.iDefragType == DEFRAG_TYPE_GEN) // DefragRam
       
   800 		{
       
   801 		returnValue = iDefragRequest.DefragRam(&sem, priority, maxPages);
       
   802 		}
       
   803 	else if (params.iDefragType == DEFRAG_TYPE_EMPTY) // EmptyRamZone
       
   804 		{
       
   805 		returnValue = iDefragRequest.EmptyRamZone(params.iID, &sem, priority);
       
   806 		}
       
   807 	else if (params.iDefragType == DEFRAG_TYPE_CLAIM) // ClaimRamZone
       
   808 		{
       
   809 		returnValue = iDefragRequest.ClaimRamZone(params.iID, zoneAddress, &sem, priority);
       
   810 		}
       
   811 	else
       
   812 		{
       
   813 		Kern::Printf("A valid defrag type was not specified");
       
   814 		return KErrGeneral;
       
   815 		}
       
   816 
       
   817 	iDefragRequest.Cancel();
       
   818 	NKern::FSWait(&sem);
       
   819 	returnValue = iDefragRequest.Result();
       
   820 	return returnValue;
       
   821 	}
       
   822 
       
   823 
       
   824 //
       
   825 // CheckPriorities
       
   826 //
       
   827 // Queue defrags with differing priorities and ensure they complete in the correct order 
       
   828 //
       
   829 TInt DRamDefragFuncTestChannel::CheckPriorities(STestParameters* aParams)
       
   830 	{
       
   831 	STestParameters params;
       
   832 	kumemget(&params, aParams, sizeof(STestParameters));
       
   833 
       
   834 	// Still have an outstanding defrag operation
       
   835 	if (iCompleteReq != NULL | iCompleteReq2 != NULL | iCompleteReq3 != NULL)
       
   836 		{
       
   837 		return KErrInUse;
       
   838 		}
       
   839 	
       
   840 	// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
   841 	// then try to complete the request on a destroyed thread.
       
   842 	iRequestThread = &Kern::CurrentThread();
       
   843 	iRequestThread->Open();
       
   844 	iCompleteReq = params.iReqStat;
       
   845 
       
   846 	// Open a reference on this channel to stop the destructor running before
       
   847 	// this defrag request has completed.
       
   848 	Open();
       
   849 	TUint defragZone = params.iID - 1;	
       
   850 	TInt returnValue = iDefragRequest.EmptyRamZone(defragZone, &iDefragCompleteDfc, 1);
       
   851 	if (returnValue != KErrNone)
       
   852 		{
       
   853 		AsyncClose();
       
   854 		iCompleteReq = NULL;
       
   855 		iRequestThread->AsyncClose();
       
   856 		iRequestThread = NULL;
       
   857 		return returnValue;
       
   858 		}
       
   859 
       
   860 	// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
   861 	// then try to complete the request on a destroyed thread.
       
   862 	iRequestThread2 = &Kern::CurrentThread();
       
   863 	iRequestThread2->Open();
       
   864 	iCompleteReq2 = params.iReqStat2;
       
   865 	// Open a reference on this channel to stop the destructor running before
       
   866 	// this defrag request has completed.
       
   867 	Open();
       
   868 	defragZone = params.iID;
       
   869 	returnValue = iDefragRequest2.EmptyRamZone(defragZone, &iDefragComplete2Dfc, 30);
       
   870 	if (returnValue != KErrNone)
       
   871 		{
       
   872 		// Cancel any successfully queued operations.
       
   873 		// Set dfcs to signal dummy request statuses as user side
       
   874 		// request status shouldn't be signalled.
       
   875 		iCompleteReq = &iTmpRequestStatus1;
       
   876 		iDefragRequest.Cancel();
       
   877 
       
   878 		// Clean up this operation.
       
   879 		AsyncClose();
       
   880 		iCompleteReq2 = NULL;
       
   881 		iRequestThread2->AsyncClose();
       
   882 		iRequestThread2 = NULL;
       
   883 		return returnValue;
       
   884 		}
       
   885 
       
   886 	// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
   887 	// then try to complete the request on a destroyed thread.
       
   888 	iRequestThread3 = &Kern::CurrentThread();
       
   889 	iRequestThread3->Open();
       
   890 	iCompleteReq3 = params.iReqStat3;
       
   891 	// Open a reference on this channel to stop the destructor running before
       
   892 	// this defrag request has completed.
       
   893 	Open();
       
   894 	defragZone = params.iID + 2;
       
   895 	returnValue = iDefragRequest3.EmptyRamZone(defragZone, &iDefragComplete3Dfc, 60);
       
   896 	if (returnValue != KErrNone)
       
   897 		{
       
   898 		// Cancel any successfully queued operations.
       
   899 		// Set dfcs to signal dummy request statuses as user side
       
   900 		// request status shouldn't be signalled.
       
   901 		iCompleteReq = &iTmpRequestStatus1;
       
   902 		iCompleteReq2 = &iTmpRequestStatus2;
       
   903 		iDefragRequest.Cancel();
       
   904 		iDefragRequest2.Cancel();
       
   905 
       
   906 		// clean up this defrag operation
       
   907 		AsyncClose();
       
   908 		iCompleteReq3 = NULL;
       
   909 		iRequestThread3->AsyncClose();
       
   910 		iRequestThread3 = NULL;
       
   911 		return returnValue;
       
   912 		}
       
   913 	return returnValue;
       
   914 	}
       
   915 
       
   916 //
       
   917 // GetDefragOrder
       
   918 //
       
   919 // Get the order in which the defrags were completed 
       
   920 //
       
   921 TInt DRamDefragFuncTestChannel::GetDefragOrder()
       
   922 	{
       
   923 	Kern::Printf("order = %d", iOrder);
       
   924 	return iOrder;
       
   925 	}
       
   926 
       
   927 
       
   928 //
       
   929 // CallDefrag
       
   930 //
       
   931 // Call a specific defrag depening on the parameters that it is called with
       
   932 //
       
   933 TInt DRamDefragFuncTestChannel::CallDefrag(STestParameters* aParams)
       
   934 	{
       
   935 	TInt returnValue = 0;
       
   936 	STestParameters params;
       
   937 	kumemget(&params, aParams, sizeof(STestParameters));
       
   938 	
       
   939 	TESTDEBUG(Kern::Printf("defragtype = %d, defragversion = %d, priority = %d, maxpages = %d, ID = %d", 
       
   940 					params.iDefragType, params.iDefragVersion, params.iPriority, params.iMaxPages, params.iID));
       
   941 
       
   942 
       
   943 	NFastSemaphore sem;
       
   944 	NKern::FSSetOwner(&sem, 0);
       
   945 
       
   946 	if (params.iDefragType == DEFRAG_TYPE_GEN) // DefragRam
       
   947 		{
       
   948 		switch(params.iDefragVersion) 
       
   949 			{
       
   950 			case DEFRAG_VER_SYNC: // Sync
       
   951 				returnValue = iDefragRequest.DefragRam(params.iPriority, params.iMaxPages);
       
   952 				break;
       
   953 			
       
   954 			case DEFRAG_VER_SEM: // Semaphore
       
   955 				returnValue = iDefragRequest.DefragRam(&sem, params.iPriority, params.iMaxPages);
       
   956 				NKern::FSWait(&sem);
       
   957 				returnValue = iDefragRequest.Result();
       
   958 				break;
       
   959 		
       
   960 			case DEFRAG_VER_DFC: // Dfc
       
   961 				// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
   962 				// then try to complete the request on a destroyed thread.
       
   963 				if (iCompleteReq == NULL)
       
   964 					{
       
   965 					iRequestThread = &Kern::CurrentThread();
       
   966 					iRequestThread->Open();
       
   967 					iCompleteReq = params.iReqStat;
       
   968 					// Open a reference on this channel to stop the destructor running before
       
   969 					// the defrag request has completed.
       
   970 					Open();
       
   971 					
       
   972 					returnValue = iDefragRequest.DefragRam(&iDefragCompleteDfc, params.iPriority, params.iMaxPages);
       
   973 					if (returnValue != KErrNone)
       
   974 						{// defrag operation didn't start so close all openned handles
       
   975 						AsyncClose();
       
   976 						iRequestThread->AsyncClose();
       
   977 						iRequestThread = NULL;
       
   978 						iCompleteReq = NULL;
       
   979 						}
       
   980 					}
       
   981 				else
       
   982 					{// Still have a pending defrag request
       
   983 					returnValue = KErrInUse;
       
   984 					}
       
   985 				break;
       
   986 				
       
   987 			default: 
       
   988 			break;	
       
   989 			}
       
   990 		}
       
   991 
       
   992 	else if (params.iDefragType == DEFRAG_TYPE_EMPTY) // EmptyRamZone
       
   993 		{
       
   994 		switch(params.iDefragVersion) 
       
   995 			{
       
   996 			case DEFRAG_VER_SYNC: // Sync
       
   997 				
       
   998 				returnValue = iDefragRequest.EmptyRamZone(params.iID, params.iPriority);
       
   999 				break;
       
  1000 			
       
  1001 			case DEFRAG_VER_SEM: // Semaphore
       
  1002 				returnValue = iDefragRequest.EmptyRamZone(params.iID, &sem, params.iPriority);
       
  1003 				NKern::FSWait(&sem);
       
  1004 				returnValue = iDefragRequest.Result();
       
  1005 				break;
       
  1006 		
       
  1007 			case DEFRAG_VER_DFC: // Dfc
       
  1008 				if (iCompleteReq == NULL)
       
  1009 					{
       
  1010 					// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
  1011 					// then try to complete the request on a destroyed thread.
       
  1012 					iRequestThread = &Kern::CurrentThread();
       
  1013 					iRequestThread->Open();
       
  1014 					iCompleteReq = params.iReqStat;
       
  1015 					// Open a reference on this channel to stop the destructor running before
       
  1016 					// the defrag request has completed.
       
  1017 					Open();
       
  1018 					
       
  1019 					returnValue = iDefragRequest.EmptyRamZone(params.iID, &iDefragCompleteDfc, params.iPriority);
       
  1020 					if (returnValue != KErrNone)
       
  1021 						{// defrag operation didn't start so close all openned handles
       
  1022 						AsyncClose();
       
  1023 						iRequestThread->AsyncClose();
       
  1024 						iRequestThread = NULL;
       
  1025 						iCompleteReq = NULL;
       
  1026 						}
       
  1027 					}
       
  1028 				else
       
  1029 					{// Still have a pending defrag request
       
  1030 					returnValue = KErrInUse;
       
  1031 					}
       
  1032 				break;
       
  1033 				
       
  1034 			default: 
       
  1035 				break;	
       
  1036 			}
       
  1037 		}
       
  1038 
       
  1039 	else if (params.iDefragType == DEFRAG_TYPE_CLAIM) // ClaimRamZone
       
  1040 		{
       
  1041 		if (iContigAddr != KPhysAddrInvalid)
       
  1042 			{
       
  1043 			return KErrInUse;
       
  1044 			}
       
  1045 		switch(params.iDefragVersion) 
       
  1046 			{
       
  1047 			case DEFRAG_VER_SYNC: // Sync
       
  1048 				
       
  1049 				returnValue = iDefragRequest.ClaimRamZone(params.iID, iContigAddr, params.iPriority);
       
  1050 				break;
       
  1051 			
       
  1052 			case DEFRAG_VER_SEM: // Semaphore
       
  1053 				returnValue = iDefragRequest.ClaimRamZone(params.iID, iContigAddr, &sem, params.iPriority);
       
  1054 				NKern::FSWait(&sem);
       
  1055 				returnValue = iDefragRequest.Result();
       
  1056 				break;
       
  1057 		
       
  1058 			case DEFRAG_VER_DFC: // Dfc
       
  1059 				if (iCompleteReq == NULL)
       
  1060 					{
       
  1061 					// Open a handle to the thread so that it isn't destroyed as defrag dfc may 
       
  1062 					// then try to complete the request on a destroyed thread.
       
  1063 					iRequestThread = &Kern::CurrentThread();
       
  1064 					iRequestThread->Open();
       
  1065 					iCompleteReq = params.iReqStat;
       
  1066 					// Open a reference on this channel to stop the destructor running before
       
  1067 					// the defrag request has completed.
       
  1068 					Open();
       
  1069 					
       
  1070 					// If the claim is successful iContigAddr will be set just before the dfc 
       
  1071 					// callback function to the physical base address of the RAM zone claimed.  
       
  1072 					// Therefore, the check for iContigAddr is not necessarily safe so use 
       
  1073 					// this DFC version with care and don't use it combination with any 
       
  1074 					// contiguous allocation methods.
       
  1075 					returnValue = iDefragRequest.ClaimRamZone(params.iID, iContigAddr, &iDefragCompleteDfc, 
       
  1076 																params.iPriority);
       
  1077 					if (returnValue != KErrNone)
       
  1078 						{// defrag operation didn't start so close all openned handles
       
  1079 						AsyncClose();
       
  1080 						iRequestThread->AsyncClose();
       
  1081 						iRequestThread = NULL;
       
  1082 						iCompleteReq = NULL;
       
  1083 						}
       
  1084 					}
       
  1085 				else
       
  1086 					{// Still have a pending defrag request
       
  1087 					returnValue = KErrInUse;
       
  1088 					}
       
  1089 				break;
       
  1090 				
       
  1091 			default: 
       
  1092 				break;
       
  1093 			}
       
  1094 		if (returnValue == KErrNone && params.iDefragVersion != DEFRAG_VER_DFC)
       
  1095 			{
       
  1096 			// Get the size of the zone just claimed so that it can be freed.  Don't set
       
  1097 			// iContigBytes for DFC method as it will be cleared by address in t_ramdefrag
       
  1098 
       
  1099 			NKern::ThreadEnterCS();
       
  1100 
       
  1101 			SRamZonePageCount pageCount;
       
  1102 			returnValue = Epoc::GetRamZonePageCount(params.iID, pageCount);
       
  1103 
       
  1104 			NKern::ThreadLeaveCS();
       
  1105 
       
  1106 			__NK_ASSERT_ALWAYS(returnValue == KErrNone); // If this fails something is seriously wrong
       
  1107 			iContigBytes = pageCount.iFixedPages << iPageShift;
       
  1108 			}
       
  1109 		else
       
  1110 			{// The claim failed so allow other contiguous allocations.
       
  1111 			iContigAddr = KPhysAddrInvalid;
       
  1112 			}
       
  1113 		}
       
  1114 
       
  1115 	return returnValue;
       
  1116 	} 
       
  1117 
       
  1118 
       
  1119 
       
  1120 //
       
  1121 // SetZoneFlag
       
  1122 //
       
  1123 // Change the flag settings of a zone
       
  1124 //
       
  1125 TInt DRamDefragFuncTestChannel::SetZoneFlag(STestFlagParams* aParams)
       
  1126 	{
       
  1127 
       
  1128 	TInt returnValue = 0;
       
  1129 	STestFlagParams flagParams;
       
  1130 	kumemget(&flagParams, aParams, sizeof(STestFlagParams));
       
  1131 	TUint setFlag = 0x0;
       
  1132 	switch(flagParams.iSetFlag)
       
  1133 		{ 
       
  1134 		case NO_FIXED_FLAG:
       
  1135 			setFlag = KRamZoneFlagNoFixed;
       
  1136 			break;
       
  1137 
       
  1138 		case NO_MOVE_FLAG:
       
  1139 			setFlag = KRamZoneFlagNoMovable;
       
  1140 			break;
       
  1141 
       
  1142 		case NO_DISCARD_FLAG:
       
  1143 			setFlag = KRamZoneFlagNoDiscard;
       
  1144 			break;
       
  1145 
       
  1146 		case NO_ALLOC_FLAG:
       
  1147 			setFlag = KRamZoneFlagNoAlloc;
       
  1148 			break;
       
  1149 
       
  1150 		case ONLY_DISCARD_FLAG:
       
  1151 			setFlag = KRamZoneFlagDiscardOnly;
       
  1152 			break;
       
  1153 		
       
  1154 		case RESET_FLAG:
       
  1155 			setFlag = 0x00;
       
  1156 			break;
       
  1157 		
       
  1158 		case ORIG_FLAG:
       
  1159 			setFlag = flagParams.iOptSetFlag;
       
  1160 			break;
       
  1161 		
       
  1162 			default: 
       
  1163 			break;	
       
  1164 		}
       
  1165 
       
  1166 	NKern::ThreadEnterCS();
       
  1167 
       
  1168 	returnValue = Epoc::ModifyRamZoneFlags(flagParams.iZoneID, flagParams.iZoneFlag, setFlag);
       
  1169 
       
  1170 	NKern::ThreadLeaveCS();
       
  1171 	return returnValue;
       
  1172 	}
       
  1173 //
       
  1174 // PageCount
       
  1175 //
       
  1176 // Call the GetRamZonePageCount function
       
  1177 //
       
  1178 TInt DRamDefragFuncTestChannel::PageCount(TUint aId, STestUserSidePageCount* aPageData)
       
  1179 	{	
       
  1180 	TInt returnValue = 0;
       
  1181 	STestUserSidePageCount pageData;
       
  1182 	SRamZonePageCount pageCount; 
       
  1183 
       
  1184 	NKern::ThreadEnterCS();
       
  1185 
       
  1186 	returnValue = Epoc::GetRamZonePageCount(aId, pageCount);
       
  1187 
       
  1188 	NKern::ThreadLeaveCS();
       
  1189 
       
  1190 	pageData.iFreePages = pageCount.iFreePages;
       
  1191 	pageData.iFixedPages = pageCount.iFixedPages;
       
  1192 	pageData.iMovablePages = pageCount.iMovablePages;
       
  1193 	pageData.iDiscardablePages = pageCount.iDiscardablePages;
       
  1194 
       
  1195 	kumemput(aPageData, &pageData, sizeof(STestUserSidePageCount));
       
  1196 	return returnValue;
       
  1197 	}
       
  1198 
       
  1199 //
       
  1200 // ZoneAllocContiguous
       
  1201 //
       
  1202 // Call the contiguous overload of the Epoc::ZoneAllocPhysicalRam() function
       
  1203 //
       
  1204 TInt DRamDefragFuncTestChannel::ZoneAllocContiguous(TUint aZoneID, TUint aNumBytes)
       
  1205 	{
       
  1206 	TInt returnValue = KErrNone;
       
  1207 	
       
  1208 	if (iContigAddr != KPhysAddrInvalid)
       
  1209 		{
       
  1210 		return KErrInUse;
       
  1211 		}
       
  1212 	iContigBytes = aNumBytes;
       
  1213 
       
  1214 	NKern::ThreadEnterCS();
       
  1215 
       
  1216 	returnValue = Epoc::ZoneAllocPhysicalRam(aZoneID, iContigBytes, iContigAddr, 0);
       
  1217 
       
  1218 	NKern::ThreadLeaveCS();
       
  1219 	
       
  1220 	if (returnValue != KErrNone)
       
  1221 		{
       
  1222 		iContigAddr = KPhysAddrInvalid;
       
  1223 		}
       
  1224 	return returnValue;
       
  1225 	}
       
  1226 
       
  1227 //
       
  1228 // ZoneAllocContiguous
       
  1229 //
       
  1230 // Call the contiguous overload of the Epoc::ZoneAllocPhysicalRam() function
       
  1231 //
       
  1232 TInt DRamDefragFuncTestChannel::ZoneAllocContiguous(TUint* aZoneIdList, TUint aZoneIdCount, TUint aNumBytes)
       
  1233 	{
       
  1234 	TInt returnValue = KErrNone;
       
  1235 	
       
  1236 	if (iContigAddr != KPhysAddrInvalid)
       
  1237 		{
       
  1238 		return KErrInUse;
       
  1239 		}
       
  1240 	iContigBytes = aNumBytes;
       
  1241 
       
  1242 	// Copy the RAM zone IDs from user side memory to kernel memory.
       
  1243 	if (aZoneIdCount > KMaxRamZones)
       
  1244 		{// Too many IDs.
       
  1245 		return KErrArgument;
       
  1246 		}
       
  1247 	kumemget32(iZoneIdArray, aZoneIdList, sizeof(TUint) * aZoneIdCount);
       
  1248 
       
  1249 	NKern::ThreadEnterCS();
       
  1250 
       
  1251 	returnValue = Epoc::ZoneAllocPhysicalRam(iZoneIdArray, aZoneIdCount, iContigBytes, iContigAddr, 0);
       
  1252 
       
  1253 	NKern::ThreadLeaveCS();
       
  1254 	
       
  1255 	if (returnValue != KErrNone)
       
  1256 		{
       
  1257 		iContigAddr = KPhysAddrInvalid;
       
  1258 		}
       
  1259 	return returnValue;
       
  1260 	}
       
  1261 
       
  1262 //
       
  1263 // AllocContiguous
       
  1264 //
       
  1265 // Call the contiguous overload of Epoc::AllocPhysicalRam()
       
  1266 //
       
  1267 TInt DRamDefragFuncTestChannel::AllocContiguous(TUint aNumBytes)
       
  1268 	{
       
  1269 	TInt returnValue = 0;
       
  1270 
       
  1271 	if (iContigAddr != KPhysAddrInvalid)
       
  1272 		{
       
  1273 		return KErrInUse;
       
  1274 		}
       
  1275 
       
  1276 	NKern::ThreadEnterCS();
       
  1277 
       
  1278 	returnValue = Epoc::AllocPhysicalRam(aNumBytes, iContigAddr, 0);
       
  1279 
       
  1280 	NKern::ThreadLeaveCS();
       
  1281 
       
  1282 	if (returnValue != KErrNone)
       
  1283 		{
       
  1284 		iContigAddr = KPhysAddrInvalid;
       
  1285 		}
       
  1286 	iContigBytes = aNumBytes;
       
  1287 	return returnValue;
       
  1288 	}
       
  1289 
       
  1290 
       
  1291 //
       
  1292 // ZoneAllocDiscontiguous
       
  1293 //
       
  1294 // Call the discontiguous overload of Epoc::ZoneAllocPhysicalRam() function
       
  1295 //
       
  1296 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(TUint aZoneId, TInt aNumPages)
       
  1297 	{
       
  1298 	TInt r = AllocFixedArray(aNumPages);
       
  1299 	if (r != KErrNone)
       
  1300 		{
       
  1301 		return r;
       
  1302 		}
       
  1303 	return ZoneAllocDiscontiguous2(aZoneId, aNumPages);
       
  1304 	}
       
  1305 
       
  1306 /**
       
  1307 Allocate the specified number of fixed pages from the specified RAM zone.
       
  1308 This should only be invoked when iAddrArray has already been allocated
       
  1309 
       
  1310 @param aZoneID		The ID of the RAM zone to allocate from
       
  1311 @param aNumPages 	The number of pages to allocate.
       
  1312 */	
       
  1313 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous2(TUint aZoneID, TInt aNumPages)
       
  1314 	{
       
  1315 	if (iAddrArray == NULL)
       
  1316 		{
       
  1317 		return KErrGeneral;
       
  1318 		}
       
  1319 
       
  1320 	NKern::ThreadEnterCS();
       
  1321 
       
  1322 	TESTDEBUG(Kern::Printf("Allocating fixed pages"));
       
  1323 	TInt returnValue = Epoc::ZoneAllocPhysicalRam(aZoneID, aNumPages, iAddrArray);
       
  1324 	
       
  1325 	if (KErrNone != returnValue)
       
  1326 		{
       
  1327 		TESTDEBUG(Kern::Printf("Alloc was unsuccessful, r = %d\n", returnValue));
       
  1328 		TESTDEBUG(Kern::Printf("aNumPages = %d, aZoneID = %d", aNumPages, aZoneID));
       
  1329 		Kern::Free(iAddrArray);
       
  1330 		iAddrArray = NULL;
       
  1331 		goto exit;
       
  1332 		}
       
  1333 	iAddrArrayPages = aNumPages;
       
  1334 	TESTDEBUG(Kern::Printf("iAddrArrayPages = %d, aZoneID = %d", iAddrArrayPages, aZoneID));
       
  1335 
       
  1336 exit:
       
  1337 	NKern::ThreadLeaveCS();
       
  1338 	return returnValue;
       
  1339 	}
       
  1340 
       
  1341 
       
  1342 //
       
  1343 // ZoneAllocDiscontiguous
       
  1344 //
       
  1345 // Call the discontiguous overload of Epoc::ZoneAllocPhysicalRam() function
       
  1346 //
       
  1347 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages)
       
  1348 	{
       
  1349 	TInt returnValue = 0;
       
  1350 	
       
  1351 	if (iAddrArray != NULL)
       
  1352 		{
       
  1353 		return KErrInUse;
       
  1354 		}
       
  1355 	NKern::ThreadEnterCS();
       
  1356 
       
  1357 	iAddrArray = new TPhysAddr[aNumPages];
       
  1358 
       
  1359 	NKern::ThreadLeaveCS();
       
  1360 
       
  1361 	if (iAddrArray == NULL)
       
  1362 		{
       
  1363 		return KErrNoMemory;
       
  1364 		}
       
  1365 
       
  1366 	// copy user side data to kernel side buffer.
       
  1367 	if (aZoneIdCount > KMaxRamZones)
       
  1368 		{// Too many IDs.
       
  1369 		return KErrArgument;
       
  1370 		}
       
  1371 	kumemget(iZoneIdArray, aZoneIdList, sizeof(TUint) * aZoneIdCount);
       
  1372 	
       
  1373 	NKern::ThreadEnterCS();
       
  1374 
       
  1375 	TESTDEBUG(Kern::Printf("Allocating fixed pages"));
       
  1376 	returnValue = Epoc::ZoneAllocPhysicalRam(iZoneIdArray, aZoneIdCount, aNumPages, iAddrArray);
       
  1377 	
       
  1378 	if (KErrNone != returnValue)
       
  1379 		{
       
  1380 		TESTDEBUG(Kern::Printf("Alloc was unsuccessful, r = %d\n", returnValue));
       
  1381 		TESTDEBUG(Kern::Printf("aNumPages = %d, aZoneID = %d", aNumPages, aZoneIdCount));
       
  1382 		delete[] iAddrArray;
       
  1383 		iAddrArray = NULL;
       
  1384 		goto exit;
       
  1385 		}
       
  1386 	iAddrArrayPages = aNumPages;
       
  1387 	TESTDEBUG(Kern::Printf("iAddrArrayPages = %d, zones = %d", iAddrArrayPages, aZoneIdCount));
       
  1388 
       
  1389 exit:
       
  1390 	NKern::ThreadLeaveCS();
       
  1391 	return returnValue;
       
  1392 	}
       
  1393 
       
  1394 //
       
  1395 // ZoneAllocToMany
       
  1396 //
       
  1397 // Call the overloaded Epoc::ZoneAllocPhysicalRam function on a number of zones
       
  1398 //
       
  1399 TInt DRamDefragFuncTestChannel::ZoneAllocToMany(TInt aZoneIndex, TInt aNumPages)
       
  1400 	{
       
  1401 	TInt r = ZoneAllocToManyArray(aZoneIndex, aNumPages);
       
  1402 	if (r != KErrNone)
       
  1403 		{
       
  1404 		return r;
       
  1405 		}
       
  1406 	return ZoneAllocToMany2(aZoneIndex, aNumPages);
       
  1407 	}
       
  1408 
       
  1409 //
       
  1410 // ZoneAllocToManyArray
       
  1411 //
       
  1412 // Allocate the arrays required to store the physical addresses of the different zones 
       
  1413 // for the number of fixed pages to be allocated to that zone.
       
  1414 //
       
  1415 TInt DRamDefragFuncTestChannel::ZoneAllocToManyArray(TInt aZoneIndex, TInt aNumPages)
       
  1416 	{
       
  1417 	TInt returnValue = KErrNone;
       
  1418 	NKern::ThreadEnterCS();
       
  1419 	
       
  1420 	if (iAddrPtrArray == NULL)
       
  1421 		{
       
  1422 		iAddrPtrArray = (TPhysAddr**)Kern::AllocZ(sizeof(TPhysAddr*) * iZoneCount);
       
  1423 		}
       
  1424 	if (iNumPagesArray == NULL)
       
  1425 		{
       
  1426 		iNumPagesArray = (TInt *)Kern::AllocZ(sizeof(TInt) * iZoneCount);
       
  1427 		}
       
  1428 	
       
  1429 	if (iAddrPtrArray[aZoneIndex] != NULL)
       
  1430 		{
       
  1431 		returnValue = KErrInUse;
       
  1432 		goto exit;
       
  1433 		}
       
  1434 	
       
  1435 	iAddrPtrArray[aZoneIndex] = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * aNumPages);
       
  1436 	if (iAddrPtrArray[aZoneIndex] == NULL)
       
  1437 		{
       
  1438 		returnValue = KErrNoMemory;
       
  1439 		goto exit;
       
  1440 		}
       
  1441 
       
  1442 exit:
       
  1443 	NKern::ThreadLeaveCS();
       
  1444 	return returnValue;
       
  1445 	}
       
  1446 
       
  1447 //
       
  1448 // ZoneAllocToMany2
       
  1449 //
       
  1450 // Call the overloaded Epoc::ZoneAllocPhysicalRam function on a number of zones
       
  1451 // This should only be invoked when iAddrPtrArray, iNumPagesArray and iAddrPtrArray[aZoneIndex]
       
  1452 // have already been allocated
       
  1453 //
       
  1454 TInt DRamDefragFuncTestChannel::ZoneAllocToMany2(TInt aZoneIndex, TInt aNumPages)
       
  1455 	{
       
  1456 	TInt returnValue = KErrNone;
       
  1457 	struct SRamZoneConfig	zoneConfig;
       
  1458 	TUint zoneID = KRamZoneInvalidId;
       
  1459 
       
  1460 	if (iAddrPtrArray == NULL ||
       
  1461 		iNumPagesArray == NULL ||
       
  1462 		iAddrPtrArray[aZoneIndex] == NULL)
       
  1463 		{
       
  1464 		return KErrGeneral;
       
  1465 		}
       
  1466 
       
  1467 
       
  1468 	NKern::ThreadEnterCS();
       
  1469 	
       
  1470 	// Get the zone ID
       
  1471 	Kern::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)aZoneIndex, (TAny*)&zoneConfig);
       
  1472 	zoneID = zoneConfig.iZoneId;
       
  1473 	returnValue = Epoc::ZoneAllocPhysicalRam(zoneID, aNumPages, iAddrPtrArray[aZoneIndex]);
       
  1474 	
       
  1475 	if (KErrNone != returnValue)
       
  1476 		{
       
  1477 		TESTDEBUG(Kern::Printf("Alloc was unsuccessful, r = %d\n", returnValue));
       
  1478 		Kern::Free(iAddrPtrArray[aZoneIndex]);
       
  1479 		iAddrPtrArray[aZoneIndex] = NULL;
       
  1480 		goto exit;
       
  1481 		}
       
  1482 	iNumPagesArray[aZoneIndex] = aNumPages;
       
  1483 
       
  1484 exit:
       
  1485 	NKern::ThreadLeaveCS();
       
  1486 	return returnValue;
       
  1487 	}
       
  1488 
       
  1489 //
       
  1490 // FreeZone
       
  1491 //
       
  1492 // Call the overloaded Epoc::FreePhysicalRam function
       
  1493 //
       
  1494 TInt DRamDefragFuncTestChannel::FreeZone(TInt aNumPages)
       
  1495 	{
       
  1496 	TInt returnValue = 0;
       
  1497 
       
  1498 	if (iAddrArray == NULL)
       
  1499 		{
       
  1500 		return KErrCorrupt;
       
  1501 		}
       
  1502 
       
  1503 	NKern::ThreadEnterCS();
       
  1504 	
       
  1505 	returnValue = Epoc::FreePhysicalRam(aNumPages, iAddrArray);
       
  1506 	
       
  1507 	Kern::Free(iAddrArray);
       
  1508 	iAddrArray = NULL;
       
  1509 
       
  1510 	NKern::ThreadLeaveCS();
       
  1511 	return returnValue;
       
  1512 	}
       
  1513 
       
  1514 //
       
  1515 // FreeFromAllZones
       
  1516 //
       
  1517 // Call the overloaded Epoc::FreePhysicalRam function
       
  1518 //
       
  1519 TInt DRamDefragFuncTestChannel::FreeFromAllZones()
       
  1520 	{
       
  1521 	TInt returnValue = 0;
       
  1522 
       
  1523 	if (iAddrPtrArray == NULL)
       
  1524 		{
       
  1525 		return KErrCorrupt;
       
  1526 		}
       
  1527 
       
  1528 	NKern::ThreadEnterCS();
       
  1529 
       
  1530 	for (TUint i=0; i<iZoneCount; i++)
       
  1531 		{
       
  1532 		if (iAddrPtrArray[i] != NULL)
       
  1533 			{
       
  1534 			returnValue = Epoc::FreePhysicalRam(iNumPagesArray[i], iAddrPtrArray[i]);
       
  1535 			iAddrPtrArray[i] = NULL;
       
  1536 			}
       
  1537 		}
       
  1538 	Kern::Free(iAddrPtrArray);
       
  1539 	iAddrPtrArray = NULL;
       
  1540 
       
  1541 	Kern::Free(iNumPagesArray);
       
  1542 	iNumPagesArray = NULL;
       
  1543 
       
  1544 	NKern::ThreadLeaveCS();	
       
  1545 	return returnValue;
       
  1546 	}
       
  1547 //
       
  1548 // FreeFromAddr
       
  1549 //
       
  1550 // Free a specific number of pages starting from a specific address
       
  1551 //
       
  1552 TInt DRamDefragFuncTestChannel::FreeFromAddr(TInt aNumPages, TUint32 aAddr)
       
  1553 	{
       
  1554 	TInt returnValue = 0;
       
  1555 	TPhysAddr address = aAddr;
       
  1556 
       
  1557 	NKern::ThreadEnterCS();
       
  1558 
       
  1559 	returnValue = Epoc::FreePhysicalRam(address, aNumPages << iPageShift);
       
  1560 
       
  1561 	NKern::ThreadLeaveCS();
       
  1562 
       
  1563 	return returnValue;
       
  1564 	}
       
  1565 
       
  1566 //
       
  1567 // FreeRam
       
  1568 //
       
  1569 // Returns the current free RAM available in bytes
       
  1570 //
       
  1571 TInt DRamDefragFuncTestChannel::FreeRam()
       
  1572 	{
       
  1573 	return Kern::FreeRamInBytes();
       
  1574 	}
       
  1575 
       
  1576 TInt DRamDefragFuncTestChannel::DoSetDebugFlag(TInt aState)
       
  1577 	{
       
  1578 	iDebug = aState;
       
  1579 	return KErrNone;
       
  1580 	}
       
  1581 
       
  1582 
       
  1583 //
       
  1584 //	DefragCompleteDfc
       
  1585 //
       
  1586 //	DFC callback called when a defrag operation has completed.
       
  1587 //
       
  1588 void DRamDefragFuncTestChannel::DefragCompleteDfc(TAny* aSelf)
       
  1589 	{
       
  1590 	// Just call non-static method
       
  1591 	TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
       
  1592 	((DRamDefragFuncTestChannel*)aSelf)->DefragComplete();
       
  1593 	}
       
  1594 
       
  1595 
       
  1596 //
       
  1597 //	DefragComplete
       
  1598 //
       
  1599 //	Invoked by the DFC callback which is called when a defrag 
       
  1600 //	operation has completed.
       
  1601 //
       
  1602 void DRamDefragFuncTestChannel::DefragComplete()
       
  1603 	{
       
  1604 	TESTDEBUG(Kern::Printf(">DDefragChannel::DefragComplete - First Defrag"));
       
  1605 	TInt result = iDefragRequest.Result();
       
  1606 	TESTDEBUG(Kern::Printf("complete code %d", result));
       
  1607 
       
  1608 	// Complete the request and close the handle to the driver
       
  1609 	Kern::SemaphoreWait(*iDefragSemaphore);
       
  1610 
       
  1611 	Kern::RequestComplete(iRequestThread, iCompleteReq, result);
       
  1612 	iCompleteReq = NULL;
       
  1613 	iRequestThread->Close(NULL);
       
  1614 	iRequestThread = NULL;
       
  1615 
       
  1616 	Kern::SemaphoreSignal(*iDefragSemaphore);
       
  1617 
       
  1618 	++iCounter;
       
  1619 	if (iCounter == 1)
       
  1620 		iOrder = 1;
       
  1621 	else if (iCounter == 2 && iOrder == 2)
       
  1622 		iOrder = 21;
       
  1623 	else if (iCounter == 2 && iOrder == 3)
       
  1624 		iOrder = 31;
       
  1625 	else if (iCounter == 3 && iOrder == 23)
       
  1626 		iOrder = 231;
       
  1627 	else if (iCounter == 3 && iOrder == 32)
       
  1628 		iOrder = 321;
       
  1629 	TESTDEBUG(Kern::Printf("order = %d", iOrder));
       
  1630 	TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
       
  1631 
       
  1632 	// Close the handle on this channel - WARNING this channel may be 
       
  1633 	// deleted immmediately after this call so don't access any members
       
  1634 	AsyncClose();
       
  1635 	}
       
  1636 
       
  1637 
       
  1638 //
       
  1639 //	Defrag2CompleteDfc
       
  1640 //
       
  1641 //	DFC callback called when a defrag operation has completed.
       
  1642 //	This is used for a particular test case when 3 
       
  1643 //	defrags are queued at the same time. 
       
  1644 //
       
  1645 void DRamDefragFuncTestChannel::Defrag2CompleteDfc(TAny* aSelf)
       
  1646 	{
       
  1647 	// Just call non-static method
       
  1648 	TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
       
  1649 	((DRamDefragFuncTestChannel*)aSelf)->Defrag2Complete();
       
  1650 	}
       
  1651 
       
  1652 
       
  1653 //
       
  1654 //	Defrag2Complete
       
  1655 //
       
  1656 //	Invoked by the DFC callback which is called when a defrag 
       
  1657 //	operation has completed. This is used for a particular test case when 3 
       
  1658 //	defrags are queued at the same time. 
       
  1659 //
       
  1660 void DRamDefragFuncTestChannel::Defrag2Complete()
       
  1661 	{
       
  1662 	TESTDEBUG(Kern::Printf(">DDefragChannel::Defrag2Complete - Second Defrag"));
       
  1663 	TInt result = iDefragRequest2.Result();
       
  1664 	TESTDEBUG(Kern::Printf("complete code %d", result));
       
  1665 	// Complete the request and close the handle to the driver
       
  1666 	Kern::SemaphoreWait(*iDefragSemaphore);
       
  1667 
       
  1668 	Kern::RequestComplete(iRequestThread2, iCompleteReq2, result);
       
  1669 	iCompleteReq2 = NULL;
       
  1670 	iRequestThread2->Close(NULL);
       
  1671 	iRequestThread2 = NULL;
       
  1672 
       
  1673 	Kern::SemaphoreSignal(*iDefragSemaphore);
       
  1674 
       
  1675 	++iCounter;
       
  1676 	if (iCounter == 1)
       
  1677 		iOrder = 2;
       
  1678 	else if (iCounter == 2 && iOrder == 1)
       
  1679 		iOrder = 12;
       
  1680 	else if (iCounter == 2 && iOrder == 3)
       
  1681 		iOrder = 32;
       
  1682 	else if (iCounter == 3 && iOrder == 13)
       
  1683 		iOrder = 132;
       
  1684 	else if (iCounter == 3 && iOrder == 31)
       
  1685 		iOrder = 312;
       
  1686 	TESTDEBUG(Kern::Printf("order = %d", iOrder));
       
  1687 	TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
       
  1688 
       
  1689 	// Close the handle on this channel - WARNING this channel may be 
       
  1690 	// deleted immmediately after this call so don't access any members
       
  1691 	AsyncClose();
       
  1692 	}
       
  1693 
       
  1694 
       
  1695 //
       
  1696 //	Defrag3CompleteDfc
       
  1697 //
       
  1698 //	DFC callback called when a defrag operation has completed. 
       
  1699 //	This is used for a particular test case when 3 
       
  1700 //	defrags are queued at the same time. 
       
  1701 //
       
  1702 void DRamDefragFuncTestChannel::Defrag3CompleteDfc(TAny* aSelf)
       
  1703 	{
       
  1704 	// Just call non-static method
       
  1705 	TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
       
  1706 	((DRamDefragFuncTestChannel*)aSelf)->Defrag3Complete();
       
  1707 	}
       
  1708 
       
  1709 //
       
  1710 //	Defrag3Complete
       
  1711 //
       
  1712 //	Invoked by the DFC callback which is called when a defrag 
       
  1713 //	operation has completed. This is used for a particular test case when 3 
       
  1714 //	defrags are queued at the same time. 
       
  1715 //
       
  1716 void DRamDefragFuncTestChannel::Defrag3Complete()
       
  1717 	{
       
  1718 	TESTDEBUG(Kern::Printf(">DDefragChannel::DefragComplete - Third Defrag"));
       
  1719 	TInt result = iDefragRequest3.Result();
       
  1720 	TESTDEBUG(Kern::Printf("complete code %d", result));
       
  1721 
       
  1722 	Kern::SemaphoreWait(*iDefragSemaphore);
       
  1723 
       
  1724 	Kern::RequestComplete(iRequestThread3, iCompleteReq3, result);
       
  1725 	iCompleteReq3 = NULL;
       
  1726 	iRequestThread3->Close(NULL);
       
  1727 	iRequestThread3 = NULL;
       
  1728 
       
  1729 	Kern::SemaphoreSignal(*iDefragSemaphore);
       
  1730 
       
  1731 
       
  1732 	++iCounter;
       
  1733 	if (iCounter == 1)
       
  1734 		iOrder = 3;
       
  1735 	else if (iCounter == 2 && iOrder == 1)
       
  1736 		iOrder = 13;
       
  1737 	else if (iCounter == 2 && iOrder == 2)
       
  1738 		iOrder = 23;
       
  1739 	else if (iCounter == 3 && iOrder == 12)
       
  1740 		iOrder = 123;
       
  1741 	else if (iCounter == 3 && iOrder == 21)
       
  1742 		iOrder = 213;
       
  1743 	TESTDEBUG(Kern::Printf("order = %d", iOrder));
       
  1744 	TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
       
  1745 
       
  1746 	// Close the handle on this channel - WARNING this channel may be 
       
  1747 	// deleted immmediately after this call so don't access any members
       
  1748 	AsyncClose();
       
  1749 	}
       
  1750 
       
  1751 //
       
  1752 // ResetDriver
       
  1753 // 
       
  1754 // Reset all the member variables in the driver
       
  1755 //
       
  1756 TInt DRamDefragFuncTestChannel::ResetDriver()
       
  1757 	{
       
  1758 	iDebug = 0; 
       
  1759 	iThreadCounter = 1; 
       
  1760 	iCounter = 0;
       
  1761 	iOrder = 0;
       
  1762 	FreeAllFixedPages();
       
  1763 
       
  1764 	return KErrNone;
       
  1765 	}