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