First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\defrag\d_testramdefrag.cpp
18 //#define DEBUG_VER // Uncomment for tracing
21 #include <kernel/kern_priv.h>
22 #include <kernel/cache.h>
23 #include "t_ramdefrag.h"
28 const TInt KMajorVersionNumber=0;
29 const TInt KMinorVersionNumber=1;
30 const TInt KBuildVersionNumber=1;
33 const TInt KDefragCompleteThreadPriority = 27;
34 _LIT(KDefragCompleteThread,"DefragCompleteThread");
36 class DRamDefragFuncTestFactory : public DLogicalDevice
40 DRamDefragFuncTestFactory();
41 ~DRamDefragFuncTestFactory();
42 virtual TInt Install();
43 virtual void GetCaps(TDes8& aDes) const;
44 virtual TInt Create(DLogicalChannelBase*& aChannel);
46 TDynamicDfcQue* iDfcQ;
49 class DRamDefragFuncTestChannel : public DLogicalChannelBase
52 DRamDefragFuncTestChannel(TDfcQue* aDfcQ);
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);
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);
79 TInt CheckCancel(STestParameters* aParams);
80 TInt CallDefrag(STestParameters* aParams);
81 TInt CheckPriorities(STestParameters* aParams);
82 TInt SetZoneFlag(STestFlagParams* aParams);
83 TInt GetDefragOrder();
85 TInt DoSetDebugFlag(TInt aState);
87 TInt ZoneAllocDiscontiguous2(TUint aZoneID, TInt aNumPages);
89 DRamDefragFuncTestFactory* iFactory;
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();
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;
109 TLinAddr iKernAddrStart;
111 TUint iPageShift; /**< The system's page shift */
113 TRamDefragRequest iDefragRequest; // Defrag request object
114 TRamDefragRequest iDefragRequest2;
115 TRamDefragRequest iDefragRequest3;
116 TUint* iZoneIdArray; /**< Pointer to an kernel heap array of zone IDs*/
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;
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
140 // DRamDefragFuncTestFactory
143 DRamDefragFuncTestFactory::DRamDefragFuncTestFactory()
148 iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
149 //iParseMask=0;//No units, no info, no PDD
150 //iUnitsMask=0;//Only one thing
153 TInt DRamDefragFuncTestFactory::Install()
155 return SetName(&KRamDefragFuncTestLddName);
158 DRamDefragFuncTestFactory::~DRamDefragFuncTestFactory()
161 {// Destroy the DFC queue created when this device drvier was loaded.
166 void DRamDefragFuncTestFactory::GetCaps(TDes8& /*aDes*/) const
168 // Not used but required as DLogicalDevice::GetCaps is pure virtual
171 TInt DRamDefragFuncTestFactory::Create(DLogicalChannelBase*& aChannel)
173 DRamDefragFuncTestChannel* channel=new DRamDefragFuncTestChannel(iDfcQ);
176 channel->iFactory = this;
181 DECLARE_STANDARD_LDD()
183 DRamDefragFuncTestFactory* factory = new DRamDefragFuncTestFactory;
186 // Allocate a kernel thread to run the DFC
187 TInt r = Kern::DynamicDfcQCreate(factory->iDfcQ, KDefragCompleteThreadPriority, KDefragCompleteThread);
190 {// Must close rather than delete factory as it is a DObject object.
191 factory->AsyncClose();
199 // DRamDefragFuncTestChannel
202 TInt DRamDefragFuncTestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
205 TInt ret = Kern::HalFunction(EHalGroupRam, ERamHalGetZoneCount, (TAny*)&iZoneCount, NULL);
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);
212 TESTDEBUG(Kern::Printf("ERROR - Unable to determine page size"));
215 TUint32 pageMask = iPageSize;
223 TESTDEBUG(Kern::Printf("ERROR - page size not a power of 2"));
224 return KErrNotSupported;
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);
239 iDefragCompleteDfc.SetDfcQ(iDfcQ);
240 iDefragComplete2Dfc.SetDfcQ(iDfcQ);
241 iDefragComplete3Dfc.SetDfcQ(iDfcQ);
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)
251 NKern::ThreadLeaveCS();
256 DRamDefragFuncTestChannel::DRamDefragFuncTestChannel(TDfcQue* aDfcQ)
258 iContigAddr(KPhysAddrInvalid),
264 iNumPagesArray(NULL),
272 iDefragSemaphore(NULL),
276 iRequestThread(NULL),
277 iRequestThread2(NULL),
278 iRequestThread3(NULL),
280 iDefragCompleteDfc(DefragCompleteDfc, (TAny*)this, 1),
281 iDefragComplete2Dfc(Defrag2CompleteDfc, (TAny*)this, 1),
282 iDefragComplete3Dfc(Defrag3CompleteDfc, (TAny*)this, 1),
288 DRamDefragFuncTestChannel::~DRamDefragFuncTestChannel()
290 if (iDefragSemaphore != NULL)
292 iDefragSemaphore->Close(NULL);
294 if (iZoneIdArray != NULL)
296 NKern::ThreadEnterCS();
297 delete[] iZoneIdArray;
298 NKern::ThreadLeaveCS();
302 TInt DRamDefragFuncTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
304 TInt threadCount = __e32_atomic_tas_ord32(&iThreadCounter, 1, 1, 0);
305 if (threadCount >= 2)
307 Kern::Printf("DRamDefragFuncTestChannel::Request threadCount = %d\n", threadCount);
310 Kern::SemaphoreWait(*iDefragSemaphore);
313 TInt retVal = KErrNotSupported;
316 case RRamDefragFuncTestLdd::EAllocateFixed:
317 retVal = DRamDefragFuncTestChannel::AllocFixedPages((TInt)a1);
320 case RRamDefragFuncTestLdd::EAllocFixedArray:
321 retVal = DRamDefragFuncTestChannel::AllocFixedArray((TInt)a1);
324 case RRamDefragFuncTestLdd::EAllocateFixed2:
325 retVal = DRamDefragFuncTestChannel::AllocateFixed2((TInt)a1);
328 case RRamDefragFuncTestLdd::EGetAllocDiff:
329 retVal = DRamDefragFuncTestChannel::GetAllocDiff((TUint)a1);
332 case RRamDefragFuncTestLdd::EFreeAllFixed:
333 retVal = DRamDefragFuncTestChannel::FreeAllFixedPages();
336 case RRamDefragFuncTestLdd::EAllocateFixedWrite:
337 retVal = DRamDefragFuncTestChannel::AllocFixedPagesWrite((TInt)a1);
340 case RRamDefragFuncTestLdd::EFreeAllFixedRead:
341 retVal = DRamDefragFuncTestChannel::FreeAllFixedPagesRead();
344 case RRamDefragFuncTestLdd::EZoneAllocContiguous:
345 retVal = DRamDefragFuncTestChannel::ZoneAllocContiguous((TUint)a1, (TUint)a2);
348 case RRamDefragFuncTestLdd::EMultiZoneAllocContiguous:
350 SMultiZoneAlloc multiZone;
351 kumemget(&multiZone, a1, sizeof(SMultiZoneAlloc));
352 retVal = DRamDefragFuncTestChannel::ZoneAllocContiguous(multiZone.iZoneId, multiZone.iZoneIdSize, (TUint)a2);
356 case RRamDefragFuncTestLdd::EZoneAllocDiscontiguous:
357 retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous((TUint)a1, (TUint)a2);
360 case RRamDefragFuncTestLdd::EMultiZoneAllocDiscontiguous:
362 SMultiZoneAlloc multiZone;
363 kumemget(&multiZone, a1, sizeof(SMultiZoneAlloc));
364 retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(multiZone.iZoneId, multiZone.iZoneIdSize, (TUint)a2);
368 case RRamDefragFuncTestLdd::EZoneAllocDiscontiguous2:
369 retVal = DRamDefragFuncTestChannel::ZoneAllocDiscontiguous2((TUint)a1, (TUint)a2);
372 case RRamDefragFuncTestLdd::EZoneAllocToMany:
373 retVal = DRamDefragFuncTestChannel::ZoneAllocToMany((TUint)a1, (TInt)a2);
376 case RRamDefragFuncTestLdd::EZoneAllocToManyArray:
377 retVal = DRamDefragFuncTestChannel::ZoneAllocToManyArray((TUint)a1, (TInt)a2);
380 case RRamDefragFuncTestLdd::EZoneAllocToMany2:
381 retVal = DRamDefragFuncTestChannel::ZoneAllocToMany2((TUint)a1, (TInt)a2);
384 case RRamDefragFuncTestLdd::EAllocContiguous:
385 retVal = DRamDefragFuncTestChannel::AllocContiguous((TUint)a1);
388 case RRamDefragFuncTestLdd::EFreeZone:
389 retVal = DRamDefragFuncTestChannel::FreeZone((TInt)a1);
392 case RRamDefragFuncTestLdd::EFreeFromAllZones:
393 retVal = DRamDefragFuncTestChannel::FreeFromAllZones();
396 case RRamDefragFuncTestLdd::EFreeFromAddr:
397 retVal = DRamDefragFuncTestChannel::FreeFromAddr((TInt)a1, (TUint32)a2);
400 case RRamDefragFuncTestLdd::EPageCount:
401 retVal = DRamDefragFuncTestChannel::PageCount((TUint)a1, (STestUserSidePageCount*)a2);
404 case RRamDefragFuncTestLdd::ECheckCancel:
405 retVal = DRamDefragFuncTestChannel::CheckCancel((STestParameters*)a1);
408 case RRamDefragFuncTestLdd::ECallDefrag:
409 retVal = DRamDefragFuncTestChannel::CallDefrag((STestParameters*)a1);
412 case RRamDefragFuncTestLdd::ESetZoneFlag:
413 retVal = DRamDefragFuncTestChannel::SetZoneFlag((STestFlagParams*)a1);
416 case RRamDefragFuncTestLdd::ECheckPriorities:
417 retVal = DRamDefragFuncTestChannel::CheckPriorities((STestParameters*)a1);
420 case RRamDefragFuncTestLdd::EGetDefragOrder:
421 retVal = DRamDefragFuncTestChannel::GetDefragOrder();
424 case RRamDefragFuncTestLdd::EDoSetDebugFlag:
425 retVal = DoSetDebugFlag((TInt) a1);
428 case RRamDefragFuncTestLdd::EResetDriver:
429 retVal = ResetDriver();
436 Kern::SemaphoreSignal(*iDefragSemaphore);
437 __e32_atomic_tas_ord32(&iThreadCounter, 1, -1, 0);
442 #define CHECK(c) { if(!(c)) { Kern::Printf("Fail %d", __LINE__); ; retVal = __LINE__;} }
448 // Free ALL of the fixed pages that were allocated
450 TInt DRamDefragFuncTestChannel::FreeAllFixedPages()
452 NKern::ThreadEnterCS();
454 TInt retVal = KErrNone;
456 if (iAddrArray != NULL)
458 retVal = Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
459 CHECK(retVal == KErrNone);
466 if (iContigAddr != KPhysAddrInvalid)
468 retVal = Epoc::FreePhysicalRam(iContigAddr, iContigBytes);
469 iContigAddr = KPhysAddrInvalid;
471 CHECK(retVal == KErrNone);
473 NKern::ThreadLeaveCS();
475 retVal = FreeFromAllZones();
482 // FreeAllFixedPagesRead()
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.
488 TInt DRamDefragFuncTestChannel::FreeAllFixedPagesRead()
491 TInt retVal = KErrNone;
494 if (iAddrArray == NULL || iChunk == NULL || !iAddrArrayPages)
499 TInt r = Kern::ChunkAddress(iChunk, 0, iAddrArrayPages << iPageShift, iKernAddrStart);
502 Kern::Printf("ERROR ? FreeAllFixedPages : Couldn't get linear address of iChunk! %d", r);
506 for (index = 0; index < iAddrArrayPages; index ++)
508 if (iAddrArray[index] != NULL)
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)
516 if (*pInt++ != index)
518 Kern::Printf("ERROR ? FreeAllFixedPages : page at index %d is corrupt! 0x%08x", index, *pInt);
524 NKern::ThreadEnterCS();
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);
530 retVal = Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
533 NKern::ThreadLeaveCS();
541 // AllocFixedPagesWrite
543 // Allocate a number of fixed pages to memory then create a shared chunk and map these pages into the chunk
545 TInt DRamDefragFuncTestChannel::AllocFixedPagesWrite(TInt aNumPages)
548 TInt retVal = KErrNone;
550 TChunkCreateInfo chunkInfo;
553 if (iAddrArray != NULL || iChunk != NULL)
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));
574 NKern::ThreadEnterCS();
576 iAddrArray = new TPhysAddr[aNumPages];
579 retVal = KErrNoMemory;
583 TESTDEBUG(Kern::Printf("amount of free pages = %d", FreeRam() >> iPageShift));
585 // create a shared chunk and map these pages into the chunk.
587 chunkInfo.iType = TChunkCreateInfo::ESharedKernelSingle;
588 chunkInfo.iMaxSize = aNumPages << iPageShift;
589 chunkInfo.iMapAttr = EMapAttrFullyBlocking;
590 chunkInfo.iOwnsMemory = EFalse;
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)
596 Kern::Printf("ChunkCreate failed retVal = %d", retVal);
600 TESTDEBUG(Kern::Printf("Created chunk - amount of free pages = %d\n", FreeRam() >> iPageShift));
602 retVal = Epoc::AllocPhysicalRam(aNumPages, iAddrArray);
603 if (retVal != KErrNone)
605 TESTDEBUG(Kern::Printf("Alloc of %d pages was unsuccessful\n", aNumPages));
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)
613 Kern::Printf("Commit was bad retVal = %d", retVal);
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 ++)
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)
629 TESTDEBUG(Kern::Printf("Allocated %d pages\n", iAddrArrayPages));
631 if (retVal != KErrNone)
632 {// Cleanup as something went wrong
635 Kern::ChunkClose(iChunk);
638 if (iAddrArray != NULL)
640 Epoc::FreePhysicalRam(iAddrArrayPages, iAddrArray);
647 NKern::ThreadLeaveCS();
651 TInt DRamDefragFuncTestChannel::GetAllocDiff(TUint aNumPages)
653 TUint initialFreeRam = FreeRam();
657 NKern::ThreadEnterCS();
659 if (iAddrArray != NULL)
664 iAddrArray = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * aNumPages);
672 ramDifference = initialFreeRam - FreeRam();
674 Kern::Free(iAddrArray);
677 ret = ramDifference >> iPageShift;
679 NKern::ThreadLeaveCS();
685 // Allocate a number of fixed pages to memory
687 TInt DRamDefragFuncTestChannel::AllocFixedPages(TInt aNumPages)
689 TInt r = AllocFixedArray(aNumPages);
694 return AllocateFixed2(aNumPages);
698 Allocate the array required to store the physical addresses of
699 number of fixed pages to be allocated.
701 @param aNumPages The number of fixed pages to be allocated.
702 @return KErrNone on success.
704 TInt DRamDefragFuncTestChannel::AllocFixedArray(TInt aNumPages)
706 if (iAddrArray != NULL)
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()));
716 NKern::ThreadEnterCS();
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.
722 NKern::ThreadLeaveCS();
733 Allocate the specified number of fixed pages.
734 This should only be invoked when iAddrArray has already been allocated
736 @param aNumPages The number of pages to allocate.
738 TInt DRamDefragFuncTestChannel::AllocateFixed2(TInt aNumPages)
740 if (iAddrArray == NULL)
744 TInt retVal = KErrNone;
745 NKern::ThreadEnterCS();
746 if (aNumPages == FILL_ALL_FIXED)
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)
754 retVal = Epoc::AllocPhysicalRam(1, addrPtr++);
755 if (retVal != KErrNone)
762 retVal = Epoc::AllocPhysicalRam(aNumPages, iAddrArray);
763 if (retVal != KErrNone)
765 TESTDEBUG(Kern::Printf("aNumPages %d FreeRam() %d", aNumPages, FreeRam()));
768 TESTDEBUG(Kern::Printf("aNumPages %d FreeRam() %d", aNumPages, FreeRam()));
769 TESTDEBUG(Kern::Printf("Fixed pages alloc was unsuccessful\n"));
772 iAddrArrayPages = aNumPages;
775 NKern::ThreadLeaveCS();
781 // Check that when a defrag is cancelled, the correct return value is reported
783 TInt DRamDefragFuncTestChannel::CheckCancel(STestParameters* aParams)
785 TInt returnValue = KErrNone;
786 STestParameters params;
787 kumemget(¶ms, aParams, sizeof(STestParameters));
789 Kern::Printf( "defragtype = %d, defragversion = %d, priority = %d, maxpages = %d, ID = %d",
790 params.iDefragType, params.iDefragVersion, params.iPriority, params.iMaxPages, params.iID);
794 NKern::FSSetOwner(&sem, 0);
795 TPhysAddr zoneAddress;
797 TInt priority = (NKern::CurrentThread()->iPriority) - 2;
799 if (params.iDefragType == DEFRAG_TYPE_GEN) // DefragRam
801 returnValue = iDefragRequest.DefragRam(&sem, priority, maxPages);
803 else if (params.iDefragType == DEFRAG_TYPE_EMPTY) // EmptyRamZone
805 returnValue = iDefragRequest.EmptyRamZone(params.iID, &sem, priority);
807 else if (params.iDefragType == DEFRAG_TYPE_CLAIM) // ClaimRamZone
809 returnValue = iDefragRequest.ClaimRamZone(params.iID, zoneAddress, &sem, priority);
813 Kern::Printf("A valid defrag type was not specified");
817 iDefragRequest.Cancel();
819 returnValue = iDefragRequest.Result();
827 // Queue defrags with differing priorities and ensure they complete in the correct order
829 TInt DRamDefragFuncTestChannel::CheckPriorities(STestParameters* aParams)
831 STestParameters params;
832 kumemget(¶ms, aParams, sizeof(STestParameters));
834 // Still have an outstanding defrag operation
835 if (iCompleteReq != NULL | iCompleteReq2 != NULL | iCompleteReq3 != NULL)
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;
846 // Open a reference on this channel to stop the destructor running before
847 // this defrag request has completed.
849 TUint defragZone = params.iID - 1;
850 TInt returnValue = iDefragRequest.EmptyRamZone(defragZone, &iDefragCompleteDfc, 1);
851 if (returnValue != KErrNone)
855 iRequestThread->AsyncClose();
856 iRequestThread = NULL;
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.
868 defragZone = params.iID;
869 returnValue = iDefragRequest2.EmptyRamZone(defragZone, &iDefragComplete2Dfc, 30);
870 if (returnValue != KErrNone)
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();
878 // Clean up this operation.
880 iCompleteReq2 = NULL;
881 iRequestThread2->AsyncClose();
882 iRequestThread2 = NULL;
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.
894 defragZone = params.iID + 2;
895 returnValue = iDefragRequest3.EmptyRamZone(defragZone, &iDefragComplete3Dfc, 60);
896 if (returnValue != KErrNone)
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();
906 // clean up this defrag operation
908 iCompleteReq3 = NULL;
909 iRequestThread3->AsyncClose();
910 iRequestThread3 = NULL;
919 // Get the order in which the defrags were completed
921 TInt DRamDefragFuncTestChannel::GetDefragOrder()
923 Kern::Printf("order = %d", iOrder);
931 // Call a specific defrag depening on the parameters that it is called with
933 TInt DRamDefragFuncTestChannel::CallDefrag(STestParameters* aParams)
935 TInt returnValue = 0;
936 STestParameters params;
937 kumemget(¶ms, aParams, sizeof(STestParameters));
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));
944 NKern::FSSetOwner(&sem, 0);
946 if (params.iDefragType == DEFRAG_TYPE_GEN) // DefragRam
948 switch(params.iDefragVersion)
950 case DEFRAG_VER_SYNC: // Sync
951 returnValue = iDefragRequest.DefragRam(params.iPriority, params.iMaxPages);
954 case DEFRAG_VER_SEM: // Semaphore
955 returnValue = iDefragRequest.DefragRam(&sem, params.iPriority, params.iMaxPages);
957 returnValue = iDefragRequest.Result();
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)
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.
972 returnValue = iDefragRequest.DefragRam(&iDefragCompleteDfc, params.iPriority, params.iMaxPages);
973 if (returnValue != KErrNone)
974 {// defrag operation didn't start so close all openned handles
976 iRequestThread->AsyncClose();
977 iRequestThread = NULL;
982 {// Still have a pending defrag request
983 returnValue = KErrInUse;
992 else if (params.iDefragType == DEFRAG_TYPE_EMPTY) // EmptyRamZone
994 switch(params.iDefragVersion)
996 case DEFRAG_VER_SYNC: // Sync
998 returnValue = iDefragRequest.EmptyRamZone(params.iID, params.iPriority);
1001 case DEFRAG_VER_SEM: // Semaphore
1002 returnValue = iDefragRequest.EmptyRamZone(params.iID, &sem, params.iPriority);
1003 NKern::FSWait(&sem);
1004 returnValue = iDefragRequest.Result();
1007 case DEFRAG_VER_DFC: // Dfc
1008 if (iCompleteReq == NULL)
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.
1019 returnValue = iDefragRequest.EmptyRamZone(params.iID, &iDefragCompleteDfc, params.iPriority);
1020 if (returnValue != KErrNone)
1021 {// defrag operation didn't start so close all openned handles
1023 iRequestThread->AsyncClose();
1024 iRequestThread = NULL;
1025 iCompleteReq = NULL;
1029 {// Still have a pending defrag request
1030 returnValue = KErrInUse;
1039 else if (params.iDefragType == DEFRAG_TYPE_CLAIM) // ClaimRamZone
1041 if (iContigAddr != KPhysAddrInvalid)
1045 switch(params.iDefragVersion)
1047 case DEFRAG_VER_SYNC: // Sync
1049 returnValue = iDefragRequest.ClaimRamZone(params.iID, iContigAddr, params.iPriority);
1052 case DEFRAG_VER_SEM: // Semaphore
1053 returnValue = iDefragRequest.ClaimRamZone(params.iID, iContigAddr, &sem, params.iPriority);
1054 NKern::FSWait(&sem);
1055 returnValue = iDefragRequest.Result();
1058 case DEFRAG_VER_DFC: // Dfc
1059 if (iCompleteReq == NULL)
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.
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,
1077 if (returnValue != KErrNone)
1078 {// defrag operation didn't start so close all openned handles
1080 iRequestThread->AsyncClose();
1081 iRequestThread = NULL;
1082 iCompleteReq = NULL;
1086 {// Still have a pending defrag request
1087 returnValue = KErrInUse;
1094 if (returnValue == KErrNone && params.iDefragVersion != DEFRAG_VER_DFC)
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
1099 NKern::ThreadEnterCS();
1101 SRamZonePageCount pageCount;
1102 returnValue = Epoc::GetRamZonePageCount(params.iID, pageCount);
1104 NKern::ThreadLeaveCS();
1106 __NK_ASSERT_ALWAYS(returnValue == KErrNone); // If this fails something is seriously wrong
1107 iContigBytes = pageCount.iFixedPages << iPageShift;
1110 {// The claim failed so allow other contiguous allocations.
1111 iContigAddr = KPhysAddrInvalid;
1123 // Change the flag settings of a zone
1125 TInt DRamDefragFuncTestChannel::SetZoneFlag(STestFlagParams* aParams)
1128 TInt returnValue = 0;
1129 STestFlagParams flagParams;
1130 kumemget(&flagParams, aParams, sizeof(STestFlagParams));
1131 TUint setFlag = 0x0;
1132 switch(flagParams.iSetFlag)
1135 setFlag = KRamZoneFlagNoFixed;
1139 setFlag = KRamZoneFlagNoMovable;
1142 case NO_DISCARD_FLAG:
1143 setFlag = KRamZoneFlagNoDiscard;
1147 setFlag = KRamZoneFlagNoAlloc;
1150 case ONLY_DISCARD_FLAG:
1151 setFlag = KRamZoneFlagDiscardOnly;
1159 setFlag = flagParams.iOptSetFlag;
1166 NKern::ThreadEnterCS();
1168 returnValue = Epoc::ModifyRamZoneFlags(flagParams.iZoneID, flagParams.iZoneFlag, setFlag);
1170 NKern::ThreadLeaveCS();
1176 // Call the GetRamZonePageCount function
1178 TInt DRamDefragFuncTestChannel::PageCount(TUint aId, STestUserSidePageCount* aPageData)
1180 TInt returnValue = 0;
1181 STestUserSidePageCount pageData;
1182 SRamZonePageCount pageCount;
1184 NKern::ThreadEnterCS();
1186 returnValue = Epoc::GetRamZonePageCount(aId, pageCount);
1188 NKern::ThreadLeaveCS();
1190 pageData.iFreePages = pageCount.iFreePages;
1191 pageData.iFixedPages = pageCount.iFixedPages;
1192 pageData.iMovablePages = pageCount.iMovablePages;
1193 pageData.iDiscardablePages = pageCount.iDiscardablePages;
1195 kumemput(aPageData, &pageData, sizeof(STestUserSidePageCount));
1200 // ZoneAllocContiguous
1202 // Call the contiguous overload of the Epoc::ZoneAllocPhysicalRam() function
1204 TInt DRamDefragFuncTestChannel::ZoneAllocContiguous(TUint aZoneID, TUint aNumBytes)
1206 TInt returnValue = KErrNone;
1208 if (iContigAddr != KPhysAddrInvalid)
1212 iContigBytes = aNumBytes;
1214 NKern::ThreadEnterCS();
1216 returnValue = Epoc::ZoneAllocPhysicalRam(aZoneID, iContigBytes, iContigAddr, 0);
1218 NKern::ThreadLeaveCS();
1220 if (returnValue != KErrNone)
1222 iContigAddr = KPhysAddrInvalid;
1228 // ZoneAllocContiguous
1230 // Call the contiguous overload of the Epoc::ZoneAllocPhysicalRam() function
1232 TInt DRamDefragFuncTestChannel::ZoneAllocContiguous(TUint* aZoneIdList, TUint aZoneIdCount, TUint aNumBytes)
1234 TInt returnValue = KErrNone;
1236 if (iContigAddr != KPhysAddrInvalid)
1240 iContigBytes = aNumBytes;
1242 // Copy the RAM zone IDs from user side memory to kernel memory.
1243 if (aZoneIdCount > KMaxRamZones)
1245 return KErrArgument;
1247 kumemget32(iZoneIdArray, aZoneIdList, sizeof(TUint) * aZoneIdCount);
1249 NKern::ThreadEnterCS();
1251 returnValue = Epoc::ZoneAllocPhysicalRam(iZoneIdArray, aZoneIdCount, iContigBytes, iContigAddr, 0);
1253 NKern::ThreadLeaveCS();
1255 if (returnValue != KErrNone)
1257 iContigAddr = KPhysAddrInvalid;
1265 // Call the contiguous overload of Epoc::AllocPhysicalRam()
1267 TInt DRamDefragFuncTestChannel::AllocContiguous(TUint aNumBytes)
1269 TInt returnValue = 0;
1271 if (iContigAddr != KPhysAddrInvalid)
1276 NKern::ThreadEnterCS();
1278 returnValue = Epoc::AllocPhysicalRam(aNumBytes, iContigAddr, 0);
1280 NKern::ThreadLeaveCS();
1282 if (returnValue != KErrNone)
1284 iContigAddr = KPhysAddrInvalid;
1286 iContigBytes = aNumBytes;
1292 // ZoneAllocDiscontiguous
1294 // Call the discontiguous overload of Epoc::ZoneAllocPhysicalRam() function
1296 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(TUint aZoneId, TInt aNumPages)
1298 TInt r = AllocFixedArray(aNumPages);
1303 return ZoneAllocDiscontiguous2(aZoneId, aNumPages);
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
1310 @param aZoneID The ID of the RAM zone to allocate from
1311 @param aNumPages The number of pages to allocate.
1313 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous2(TUint aZoneID, TInt aNumPages)
1315 if (iAddrArray == NULL)
1320 NKern::ThreadEnterCS();
1322 TESTDEBUG(Kern::Printf("Allocating fixed pages"));
1323 TInt returnValue = Epoc::ZoneAllocPhysicalRam(aZoneID, aNumPages, iAddrArray);
1325 if (KErrNone != returnValue)
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);
1333 iAddrArrayPages = aNumPages;
1334 TESTDEBUG(Kern::Printf("iAddrArrayPages = %d, aZoneID = %d", iAddrArrayPages, aZoneID));
1337 NKern::ThreadLeaveCS();
1343 // ZoneAllocDiscontiguous
1345 // Call the discontiguous overload of Epoc::ZoneAllocPhysicalRam() function
1347 TInt DRamDefragFuncTestChannel::ZoneAllocDiscontiguous(TUint* aZoneIdList, TUint aZoneIdCount, TInt aNumPages)
1349 TInt returnValue = 0;
1351 if (iAddrArray != NULL)
1355 NKern::ThreadEnterCS();
1357 iAddrArray = new TPhysAddr[aNumPages];
1359 NKern::ThreadLeaveCS();
1361 if (iAddrArray == NULL)
1363 return KErrNoMemory;
1366 // copy user side data to kernel side buffer.
1367 if (aZoneIdCount > KMaxRamZones)
1369 return KErrArgument;
1371 kumemget(iZoneIdArray, aZoneIdList, sizeof(TUint) * aZoneIdCount);
1373 NKern::ThreadEnterCS();
1375 TESTDEBUG(Kern::Printf("Allocating fixed pages"));
1376 returnValue = Epoc::ZoneAllocPhysicalRam(iZoneIdArray, aZoneIdCount, aNumPages, iAddrArray);
1378 if (KErrNone != returnValue)
1380 TESTDEBUG(Kern::Printf("Alloc was unsuccessful, r = %d\n", returnValue));
1381 TESTDEBUG(Kern::Printf("aNumPages = %d, aZoneID = %d", aNumPages, aZoneIdCount));
1382 delete[] iAddrArray;
1386 iAddrArrayPages = aNumPages;
1387 TESTDEBUG(Kern::Printf("iAddrArrayPages = %d, zones = %d", iAddrArrayPages, aZoneIdCount));
1390 NKern::ThreadLeaveCS();
1397 // Call the overloaded Epoc::ZoneAllocPhysicalRam function on a number of zones
1399 TInt DRamDefragFuncTestChannel::ZoneAllocToMany(TInt aZoneIndex, TInt aNumPages)
1401 TInt r = ZoneAllocToManyArray(aZoneIndex, aNumPages);
1406 return ZoneAllocToMany2(aZoneIndex, aNumPages);
1410 // ZoneAllocToManyArray
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.
1415 TInt DRamDefragFuncTestChannel::ZoneAllocToManyArray(TInt aZoneIndex, TInt aNumPages)
1417 TInt returnValue = KErrNone;
1418 NKern::ThreadEnterCS();
1420 if (iAddrPtrArray == NULL)
1422 iAddrPtrArray = (TPhysAddr**)Kern::AllocZ(sizeof(TPhysAddr*) * iZoneCount);
1424 if (iNumPagesArray == NULL)
1426 iNumPagesArray = (TInt *)Kern::AllocZ(sizeof(TInt) * iZoneCount);
1429 if (iAddrPtrArray[aZoneIndex] != NULL)
1431 returnValue = KErrInUse;
1435 iAddrPtrArray[aZoneIndex] = (TPhysAddr *)Kern::AllocZ(sizeof(TPhysAddr) * aNumPages);
1436 if (iAddrPtrArray[aZoneIndex] == NULL)
1438 returnValue = KErrNoMemory;
1443 NKern::ThreadLeaveCS();
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
1454 TInt DRamDefragFuncTestChannel::ZoneAllocToMany2(TInt aZoneIndex, TInt aNumPages)
1456 TInt returnValue = KErrNone;
1457 struct SRamZoneConfig zoneConfig;
1458 TUint zoneID = KRamZoneInvalidId;
1460 if (iAddrPtrArray == NULL ||
1461 iNumPagesArray == NULL ||
1462 iAddrPtrArray[aZoneIndex] == NULL)
1468 NKern::ThreadEnterCS();
1471 Kern::HalFunction(EHalGroupRam,ERamHalGetZoneConfig,(TAny*)aZoneIndex, (TAny*)&zoneConfig);
1472 zoneID = zoneConfig.iZoneId;
1473 returnValue = Epoc::ZoneAllocPhysicalRam(zoneID, aNumPages, iAddrPtrArray[aZoneIndex]);
1475 if (KErrNone != returnValue)
1477 TESTDEBUG(Kern::Printf("Alloc was unsuccessful, r = %d\n", returnValue));
1478 Kern::Free(iAddrPtrArray[aZoneIndex]);
1479 iAddrPtrArray[aZoneIndex] = NULL;
1482 iNumPagesArray[aZoneIndex] = aNumPages;
1485 NKern::ThreadLeaveCS();
1492 // Call the overloaded Epoc::FreePhysicalRam function
1494 TInt DRamDefragFuncTestChannel::FreeZone(TInt aNumPages)
1496 TInt returnValue = 0;
1498 if (iAddrArray == NULL)
1503 NKern::ThreadEnterCS();
1505 returnValue = Epoc::FreePhysicalRam(aNumPages, iAddrArray);
1507 Kern::Free(iAddrArray);
1510 NKern::ThreadLeaveCS();
1517 // Call the overloaded Epoc::FreePhysicalRam function
1519 TInt DRamDefragFuncTestChannel::FreeFromAllZones()
1521 TInt returnValue = 0;
1523 if (iAddrPtrArray == NULL)
1528 NKern::ThreadEnterCS();
1530 for (TUint i=0; i<iZoneCount; i++)
1532 if (iAddrPtrArray[i] != NULL)
1534 returnValue = Epoc::FreePhysicalRam(iNumPagesArray[i], iAddrPtrArray[i]);
1535 iAddrPtrArray[i] = NULL;
1538 Kern::Free(iAddrPtrArray);
1539 iAddrPtrArray = NULL;
1541 Kern::Free(iNumPagesArray);
1542 iNumPagesArray = NULL;
1544 NKern::ThreadLeaveCS();
1550 // Free a specific number of pages starting from a specific address
1552 TInt DRamDefragFuncTestChannel::FreeFromAddr(TInt aNumPages, TUint32 aAddr)
1554 TInt returnValue = 0;
1555 TPhysAddr address = aAddr;
1557 NKern::ThreadEnterCS();
1559 returnValue = Epoc::FreePhysicalRam(address, aNumPages << iPageShift);
1561 NKern::ThreadLeaveCS();
1569 // Returns the current free RAM available in bytes
1571 TInt DRamDefragFuncTestChannel::FreeRam()
1573 return Kern::FreeRamInBytes();
1576 TInt DRamDefragFuncTestChannel::DoSetDebugFlag(TInt aState)
1584 // DefragCompleteDfc
1586 // DFC callback called when a defrag operation has completed.
1588 void DRamDefragFuncTestChannel::DefragCompleteDfc(TAny* aSelf)
1590 // Just call non-static method
1591 TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
1592 ((DRamDefragFuncTestChannel*)aSelf)->DefragComplete();
1599 // Invoked by the DFC callback which is called when a defrag
1600 // operation has completed.
1602 void DRamDefragFuncTestChannel::DefragComplete()
1604 TESTDEBUG(Kern::Printf(">DDefragChannel::DefragComplete - First Defrag"));
1605 TInt result = iDefragRequest.Result();
1606 TESTDEBUG(Kern::Printf("complete code %d", result));
1608 // Complete the request and close the handle to the driver
1609 Kern::SemaphoreWait(*iDefragSemaphore);
1611 Kern::RequestComplete(iRequestThread, iCompleteReq, result);
1612 iCompleteReq = NULL;
1613 iRequestThread->Close(NULL);
1614 iRequestThread = NULL;
1616 Kern::SemaphoreSignal(*iDefragSemaphore);
1621 else if (iCounter == 2 && iOrder == 2)
1623 else if (iCounter == 2 && iOrder == 3)
1625 else if (iCounter == 3 && iOrder == 23)
1627 else if (iCounter == 3 && iOrder == 32)
1629 TESTDEBUG(Kern::Printf("order = %d", iOrder));
1630 TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
1632 // Close the handle on this channel - WARNING this channel may be
1633 // deleted immmediately after this call so don't access any members
1639 // Defrag2CompleteDfc
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.
1645 void DRamDefragFuncTestChannel::Defrag2CompleteDfc(TAny* aSelf)
1647 // Just call non-static method
1648 TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
1649 ((DRamDefragFuncTestChannel*)aSelf)->Defrag2Complete();
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.
1660 void DRamDefragFuncTestChannel::Defrag2Complete()
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);
1668 Kern::RequestComplete(iRequestThread2, iCompleteReq2, result);
1669 iCompleteReq2 = NULL;
1670 iRequestThread2->Close(NULL);
1671 iRequestThread2 = NULL;
1673 Kern::SemaphoreSignal(*iDefragSemaphore);
1678 else if (iCounter == 2 && iOrder == 1)
1680 else if (iCounter == 2 && iOrder == 3)
1682 else if (iCounter == 3 && iOrder == 13)
1684 else if (iCounter == 3 && iOrder == 31)
1686 TESTDEBUG(Kern::Printf("order = %d", iOrder));
1687 TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
1689 // Close the handle on this channel - WARNING this channel may be
1690 // deleted immmediately after this call so don't access any members
1696 // Defrag3CompleteDfc
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.
1702 void DRamDefragFuncTestChannel::Defrag3CompleteDfc(TAny* aSelf)
1704 // Just call non-static method
1705 TESTDEBUG(Kern::Printf("Calling DefragCompleteDfc"));
1706 ((DRamDefragFuncTestChannel*)aSelf)->Defrag3Complete();
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.
1716 void DRamDefragFuncTestChannel::Defrag3Complete()
1718 TESTDEBUG(Kern::Printf(">DDefragChannel::DefragComplete - Third Defrag"));
1719 TInt result = iDefragRequest3.Result();
1720 TESTDEBUG(Kern::Printf("complete code %d", result));
1722 Kern::SemaphoreWait(*iDefragSemaphore);
1724 Kern::RequestComplete(iRequestThread3, iCompleteReq3, result);
1725 iCompleteReq3 = NULL;
1726 iRequestThread3->Close(NULL);
1727 iRequestThread3 = NULL;
1729 Kern::SemaphoreSignal(*iDefragSemaphore);
1735 else if (iCounter == 2 && iOrder == 1)
1737 else if (iCounter == 2 && iOrder == 2)
1739 else if (iCounter == 3 && iOrder == 12)
1741 else if (iCounter == 3 && iOrder == 21)
1743 TESTDEBUG(Kern::Printf("order = %d", iOrder));
1744 TESTDEBUG(Kern::Printf("<DDefragChannel::DefragComplete"));
1746 // Close the handle on this channel - WARNING this channel may be
1747 // deleted immmediately after this call so don't access any members
1754 // Reset all the member variables in the driver
1756 TInt DRamDefragFuncTestChannel::ResetDriver()
1762 FreeAllFixedPages();