|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include "loadgen_memoryeat.h" |
|
21 #include "loadgen_model.h" |
|
22 #include "loadgen.hrh" |
|
23 #include "loadgen_traces.h" |
|
24 #include <loadgen.rsg> |
|
25 |
|
26 #include <e32math.h> |
|
27 |
|
28 _LIT(KThreadName, "MemEat %d"); |
|
29 _LIT(KChunkName, "LoadGen %d"); |
|
30 _LIT(KFilePath, "%c:\\system\\temp\\LoadGen-%d_%d.$$$"); |
|
31 |
|
32 // currently can only handle 2GB |
|
33 const TInt64 KMaxEatSize = 2147483647; |
|
34 |
|
35 const TInt KDefaultStart = 50; |
|
36 const TInt KDefaultPeriod = 5000000; |
|
37 |
|
38 // ===================================== MEMBER FUNCTIONS ===================================== |
|
39 |
|
40 CMemoryEat* CMemoryEat::NewL(TMemoryEatAttributes& aAttributes, TInt aReferenceNumber) |
|
41 { |
|
42 CMemoryEat* self = new(ELeave) CMemoryEat(aAttributes, aReferenceNumber); |
|
43 CleanupStack::PushL(self); |
|
44 self->ConstructL(); |
|
45 CleanupStack::Pop(self); |
|
46 return self; |
|
47 } |
|
48 |
|
49 // -------------------------------------------------------------------------------------------- |
|
50 |
|
51 CMemoryEat::~CMemoryEat() |
|
52 { |
|
53 Close(); |
|
54 } |
|
55 |
|
56 // -------------------------------------------------------------------------------------------- |
|
57 |
|
58 CMemoryEat::CMemoryEat(TMemoryEatAttributes& aAttributes, TInt aReferenceNumber) : iAttributes(aAttributes) |
|
59 { |
|
60 iAttributes.iId = aReferenceNumber; |
|
61 } |
|
62 |
|
63 // -------------------------------------------------------------------------------------------- |
|
64 |
|
65 void CMemoryEat::ConstructL() |
|
66 { |
|
67 CLoadBase::ConstructL(); |
|
68 |
|
69 iType = ELoadGenCmdNewLoadEatMemory; |
|
70 |
|
71 TBuf<64> threadName; |
|
72 threadName.Format(KThreadName, iAttributes.iId); |
|
73 |
|
74 // create a thread |
|
75 User::LeaveIfError(iThread.Create(threadName, ThreadFunction, KDefaultStackSize*2, KMinHeapSize, 32*1024*KMinHeapSize, (TAny*) &iAttributes )); |
|
76 |
|
77 // set priority of the thread |
|
78 SetPriority(); |
|
79 } |
|
80 |
|
81 // -------------------------------------------------------------------------------------------- |
|
82 |
|
83 TInt CMemoryEat::ThreadFunction(TAny* aThreadArg) |
|
84 { |
|
85 CTrapCleanup* pC = CTrapCleanup::New(); |
|
86 CActiveScheduler* pS = new CActiveScheduler; |
|
87 CActiveScheduler::Install(pS); |
|
88 |
|
89 // start memory eat, pass pointer to arguments |
|
90 GenerateLoad(*((TMemoryEatAttributes*) aThreadArg)); |
|
91 |
|
92 delete pS; |
|
93 delete pC; |
|
94 |
|
95 return KErrNone; |
|
96 } |
|
97 |
|
98 // -------------------------------------------------------------------------------------------- |
|
99 |
|
100 void CMemoryEat::GenerateLoad(TMemoryEatAttributes& aAttributes) |
|
101 { |
|
102 CMemoryEatManager* memoryEatManager = NULL; |
|
103 TRAPD(err, memoryEatManager = CMemoryEatManager::NewL(aAttributes)); |
|
104 if (err == KErrNone) CActiveScheduler::Start(); |
|
105 delete memoryEatManager; |
|
106 } |
|
107 |
|
108 // -------------------------------------------------------------------------------------------- |
|
109 |
|
110 void CMemoryEat::Resume() |
|
111 { |
|
112 CLoadBase::Resume(); |
|
113 |
|
114 iThread.Resume(); |
|
115 } |
|
116 |
|
117 // -------------------------------------------------------------------------------------------- |
|
118 |
|
119 void CMemoryEat::Suspend() |
|
120 { |
|
121 CLoadBase::Suspend(); |
|
122 |
|
123 iThread.Suspend(); |
|
124 } |
|
125 |
|
126 // -------------------------------------------------------------------------------------------- |
|
127 |
|
128 void CMemoryEat::SetPriority() |
|
129 { |
|
130 CLoadBase::SetPriority(); |
|
131 |
|
132 iThread.SetPriority(CLoadGenModel::SettingItemToThreadPriority(iAttributes.iPriority)); |
|
133 } |
|
134 |
|
135 // -------------------------------------------------------------------------------------------- |
|
136 |
|
137 void CMemoryEat::Close() |
|
138 { |
|
139 CLoadBase::Close(); |
|
140 |
|
141 if (iThread.ExitReason() == 0) // check if the thread is still alive |
|
142 { |
|
143 // signal the thread that it needs to close |
|
144 iThread.RequestComplete(iAttributes.iDeathStatus, KErrCancel); |
|
145 |
|
146 // wait the thread to die |
|
147 TRequestStatus waiter; |
|
148 iThread.Logon(waiter); |
|
149 User::WaitForRequest(waiter); |
|
150 iThread.Close(); |
|
151 } |
|
152 } |
|
153 |
|
154 // -------------------------------------------------------------------------------------------- |
|
155 |
|
156 TPtrC CMemoryEat::Description() |
|
157 { |
|
158 TBuf<256> buf; |
|
159 TBuf<16> prioBuf; |
|
160 CLoadGenModel::SettingItemToThreadDescription(iAttributes.iPriority, prioBuf); |
|
161 TBuf<16> srcBuf; |
|
162 CLoadGenModel::SettingItemToSourceDescription(iAttributes.iSource, srcBuf); |
|
163 |
|
164 if (iAttributes.iType == EMemoryEatTypeMemoryToEat) |
|
165 { |
|
166 _LIT(KMemoryEatEntryMemoryToEat, "[%d] MemEat src=%S prio=%S type=MemToEat amount=%LDB buf=%dB idle=%dms"); |
|
167 |
|
168 buf.Format(KMemoryEatEntryMemoryToEat, iAttributes.iId, &srcBuf, &prioBuf, iAttributes.iAmount, iAttributes.iBuffer, iAttributes.iIdle); |
|
169 } |
|
170 else if (iAttributes.iType == EMemoryEatTypeMemoryToBeLeft) |
|
171 { |
|
172 _LIT(KMemoryEatEntryMemoryToBeLeft, "[%d] MemEat src=%S prio=%S type=MemToBeLeft amount=%LDB buf=%dB idle=%dms"); |
|
173 |
|
174 buf.Format(KMemoryEatEntryMemoryToBeLeft, iAttributes.iId, &srcBuf, &prioBuf, iAttributes.iAmount, iAttributes.iBuffer, iAttributes.iIdle); |
|
175 } |
|
176 |
|
177 else if (iAttributes.iType == EMemoryEatTypeWavy) |
|
178 { |
|
179 _LIT(KMemoryEatEntryRandom, "[%d] MemEat src=%S prio=%S type=Random min=%LDB max=%LDB buf=%dB idle=%dms"); |
|
180 |
|
181 buf.Format(KMemoryEatEntryRandom, iAttributes.iId, &srcBuf, &prioBuf, iAttributes.iRandomMin, iAttributes.iRandomMax, iAttributes.iBuffer, iAttributes.iIdle); |
|
182 } |
|
183 |
|
184 return TPtrC(buf); |
|
185 } |
|
186 |
|
187 // -------------------------------------------------------------------------------------------- |
|
188 // -------------------------------------------------------------------------------------------- |
|
189 |
|
190 CMemoryEatManager* CMemoryEatManager::NewL(TMemoryEatAttributes& aAttributes) |
|
191 { |
|
192 CMemoryEatManager* self = new(ELeave) CMemoryEatManager(aAttributes); |
|
193 CleanupStack::PushL(self); |
|
194 self->ConstructL(); |
|
195 CleanupStack::Pop(); |
|
196 return self; |
|
197 } |
|
198 |
|
199 // -------------------------------------------------------------------------------------------- |
|
200 |
|
201 CMemoryEatManager::CMemoryEatManager(TMemoryEatAttributes& aAttributes) : |
|
202 CActive(EPriorityStandard), iAttributes(aAttributes) |
|
203 { |
|
204 } |
|
205 |
|
206 // -------------------------------------------------------------------------------------------- |
|
207 |
|
208 CMemoryEatManager::~CMemoryEatManager() |
|
209 { |
|
210 Cancel(); |
|
211 DestroyMemoryEat(); |
|
212 } |
|
213 |
|
214 // -------------------------------------------------------------------------------------------- |
|
215 |
|
216 void CMemoryEatManager::ConstructL() |
|
217 { |
|
218 CActiveScheduler::Add(this); |
|
219 |
|
220 // set the status as pending |
|
221 iStatus = KRequestPending; |
|
222 SetActive(); |
|
223 |
|
224 // set the death status pointer point to the request status of this ao |
|
225 iAttributes.iDeathStatus = &iStatus; |
|
226 |
|
227 // init |
|
228 InitMemoryEatL(); |
|
229 |
|
230 // start timer |
|
231 iPeriodicTimer = CPeriodic::NewL(CActive::EPriorityStandard); |
|
232 iPeriodicTimer->Start(KDefaultStart, KDefaultPeriod, TCallBack(PeriodicTimerCallBack, this)); |
|
233 } |
|
234 |
|
235 // -------------------------------------------------------------------------------------------- |
|
236 |
|
237 void CMemoryEatManager::RunL() |
|
238 { |
|
239 // request status has completed by the main thread meaning that we need to stop now |
|
240 CActiveScheduler::Stop(); |
|
241 } |
|
242 |
|
243 // -------------------------------------------------------------------------------------------- |
|
244 |
|
245 void CMemoryEatManager::DoCancel() |
|
246 { |
|
247 } |
|
248 |
|
249 // -------------------------------------------------------------------------------------------- |
|
250 |
|
251 TInt CMemoryEatManager::PeriodicTimerCallBack(TAny* aAny) |
|
252 { |
|
253 TInt result = KErrNone; |
|
254 CMemoryEatManager* self = static_cast<CMemoryEatManager*>( aAny ); |
|
255 |
|
256 self->iPeriodicTimer->Cancel(); |
|
257 TRAP( result, self->EatMemoryL() ); |
|
258 |
|
259 return result; |
|
260 } |
|
261 |
|
262 // -------------------------------------------------------------------------------------------- |
|
263 |
|
264 void CMemoryEatManager::InitMemoryEatL() |
|
265 { |
|
266 // create a chunk for RAM |
|
267 if (iAttributes.iSource == EMemoryEatSourceTypeRAM) |
|
268 { |
|
269 TBuf<64> chunkName; |
|
270 chunkName.Format(KChunkName, iAttributes.iId); |
|
271 |
|
272 // set max size of the chunk to be size of the RAM memory |
|
273 TMemoryInfoV1Buf ramMemory; |
|
274 UserHal::MemoryInfo(ramMemory); |
|
275 |
|
276 User::LeaveIfError( iEatChunk.CreateGlobal(chunkName, 0, ramMemory().iMaxFreeRamInBytes-1, EOwnerThread) ); |
|
277 } |
|
278 |
|
279 // create a temporary file to disk |
|
280 else |
|
281 { |
|
282 // connect to RFs |
|
283 User::LeaveIfError( iFs.Connect() ); |
|
284 |
|
285 iFilesCounter = 0; |
|
286 |
|
287 TFileName eatFileName; |
|
288 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, 1 ); |
|
289 |
|
290 iFs.MkDirAll( eatFileName ); |
|
291 User::LeaveIfError( iEatFile.Replace( iFs, eatFileName, EFileWrite ) ); |
|
292 iFilesCounter++; |
|
293 } |
|
294 |
|
295 iWavyEatMoreMemory = ETrue; |
|
296 } |
|
297 |
|
298 // -------------------------------------------------------------------------------------------- |
|
299 |
|
300 void CMemoryEatManager::DestroyMemoryEat() |
|
301 { |
|
302 if (iAttributes.iSource == EMemoryEatSourceTypeRAM) |
|
303 { |
|
304 iEatChunk.Adjust(0); |
|
305 iEatChunk.Close(); |
|
306 } |
|
307 else |
|
308 { |
|
309 // close current file |
|
310 |
|
311 iEatFile.Flush(); |
|
312 iEatFile.Close(); |
|
313 |
|
314 // delete created files |
|
315 for ( TInt k = 1; k <= iFilesCounter; k++ ) |
|
316 { |
|
317 TFileName eatFileName; |
|
318 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, k ); |
|
319 iFs.Delete( eatFileName ); |
|
320 } |
|
321 iFs.Close(); |
|
322 } |
|
323 } |
|
324 |
|
325 // -------------------------------------------------------------------------------------------- |
|
326 |
|
327 void CMemoryEatManager::EatMemoryL() |
|
328 { |
|
329 // get current sizes |
|
330 TInt64 eatSizeNow(0); |
|
331 TInt sizeNow(0); |
|
332 TInt64 freeSystemMemory(0); |
|
333 |
|
334 if (iAttributes.iSource == EMemoryEatSourceTypeRAM) |
|
335 { |
|
336 eatSizeNow = iEatChunk.Size(); // get current chunk size |
|
337 } |
|
338 else |
|
339 { |
|
340 User::LeaveIfError( iEatFile.Size( sizeNow ) ); |
|
341 if ( iFilesCounter > 1) |
|
342 { |
|
343 eatSizeNow += sizeNow + ( ( iFilesCounter - 1 ) * KMaxEatSize ); |
|
344 } |
|
345 else |
|
346 { |
|
347 eatSizeNow = sizeNow ; |
|
348 } |
|
349 } |
|
350 LOGSTRING2("Loadgen:EatMemoryL eatSizeNow = %d", eatSizeNow ); |
|
351 |
|
352 freeSystemMemory = ReadFreeMemory(); |
|
353 |
|
354 // eat until specific amount of memory at most amount of buffer at a time |
|
355 if (iAttributes.iType == EMemoryEatTypeMemoryToEat) |
|
356 { |
|
357 // grow partial buffer to match exact amount |
|
358 if ( ( iAttributes.iAmount - eatSizeNow >= 0 && |
|
359 iAttributes.iAmount - eatSizeNow < iAttributes.iBuffer ) ) |
|
360 { |
|
361 DoEatMemoryL( eatSizeNow + ( iAttributes.iAmount - eatSizeNow ) ); |
|
362 } |
|
363 |
|
364 // grow full buffer |
|
365 else if ( eatSizeNow < iAttributes.iAmount ) |
|
366 { |
|
367 DoEatMemoryL( eatSizeNow + iAttributes.iBuffer ); |
|
368 } |
|
369 // shrink partial buffer to match exact amount |
|
370 else if (eatSizeNow - iAttributes.iAmount >= 0 && eatSizeNow - iAttributes.iAmount < iAttributes.iBuffer) |
|
371 { |
|
372 DoEatMemoryL(eatSizeNow - (eatSizeNow - iAttributes.iAmount)); |
|
373 } |
|
374 |
|
375 // shrink full buffer |
|
376 else if (eatSizeNow > iAttributes.iAmount) |
|
377 { |
|
378 DoEatMemoryL(eatSizeNow - iAttributes.iBuffer); |
|
379 } |
|
380 } |
|
381 |
|
382 |
|
383 // eat until specific amount of free memory has been reached at most amount of buffer at a time |
|
384 else if (iAttributes.iType == EMemoryEatTypeMemoryToBeLeft) |
|
385 { |
|
386 // grow partial buffer to match exact amount |
|
387 if (freeSystemMemory - iAttributes.iAmount >= 0 && freeSystemMemory - iAttributes.iAmount < iAttributes.iBuffer) |
|
388 { |
|
389 DoEatMemoryL(eatSizeNow + (freeSystemMemory - iAttributes.iAmount)); |
|
390 } |
|
391 |
|
392 // grow full buffer |
|
393 else if (freeSystemMemory > iAttributes.iAmount) |
|
394 { |
|
395 DoEatMemoryL(eatSizeNow + iAttributes.iBuffer); |
|
396 } |
|
397 |
|
398 // shrink partial buffer to match exact amount |
|
399 if (iAttributes.iAmount - freeSystemMemory >= 0 && iAttributes.iAmount - freeSystemMemory < iAttributes.iBuffer) |
|
400 { |
|
401 DoEatMemoryL(eatSizeNow - (iAttributes.iAmount - freeSystemMemory)); |
|
402 } |
|
403 |
|
404 // shrink full buffer |
|
405 else if (freeSystemMemory < iAttributes.iAmount) |
|
406 { |
|
407 DoEatMemoryL(eatSizeNow - iAttributes.iBuffer); |
|
408 } |
|
409 } |
|
410 |
|
411 // wavy memory eat |
|
412 else if (iAttributes.iType == EMemoryEatTypeWavy) |
|
413 { |
|
414 // grow to max value if not under it |
|
415 if (freeSystemMemory > iAttributes.iRandomMax) |
|
416 { |
|
417 DoEatMemoryL(eatSizeNow + (freeSystemMemory - iAttributes.iRandomMax) + iAttributes.iBuffer); |
|
418 iWavyEatMoreMemory = ETrue; // change direction |
|
419 } |
|
420 |
|
421 // shrink to min value if not below it |
|
422 else if (freeSystemMemory < iAttributes.iRandomMin) |
|
423 { |
|
424 DoEatMemoryL(eatSizeNow - (iAttributes.iRandomMin - freeSystemMemory) - iAttributes.iBuffer); |
|
425 iWavyEatMoreMemory = EFalse; // change direction |
|
426 } |
|
427 |
|
428 // grow or shrink |
|
429 else |
|
430 { |
|
431 if (iWavyEatMoreMemory) |
|
432 { |
|
433 // grow partial buffer to match exact amount |
|
434 if (freeSystemMemory - iAttributes.iRandomMin >= 0 && freeSystemMemory - iAttributes.iRandomMin < iAttributes.iBuffer) |
|
435 { |
|
436 DoEatMemoryL(eatSizeNow + (freeSystemMemory - iAttributes.iRandomMin)); |
|
437 iWavyEatMoreMemory = EFalse; // change direction since limit reached |
|
438 } |
|
439 |
|
440 // grow full buffer |
|
441 else |
|
442 { |
|
443 DoEatMemoryL(eatSizeNow + iAttributes.iBuffer); |
|
444 } |
|
445 } |
|
446 |
|
447 else // shrink |
|
448 { |
|
449 // shrink partial buffer to match exact amount |
|
450 if (iAttributes.iRandomMax - freeSystemMemory >= 0 && iAttributes.iRandomMax - freeSystemMemory < iAttributes.iBuffer) |
|
451 { |
|
452 DoEatMemoryL(eatSizeNow - (iAttributes.iRandomMax - freeSystemMemory)); |
|
453 iWavyEatMoreMemory = ETrue; // change direction since limit reached |
|
454 } |
|
455 |
|
456 // shrink full buffer |
|
457 else |
|
458 { |
|
459 DoEatMemoryL(eatSizeNow - iAttributes.iBuffer); |
|
460 } |
|
461 } |
|
462 } |
|
463 } |
|
464 |
|
465 |
|
466 // call timer |
|
467 iPeriodicTimer->Start(CLoadGenModel::MilliSecondsToMicroSeconds(iAttributes.iIdle, iAttributes.iRandomVariance), KDefaultPeriod, TCallBack(PeriodicTimerCallBack, this)); |
|
468 } |
|
469 |
|
470 // -------------------------------------------------------------------------------------------- |
|
471 |
|
472 void CMemoryEatManager::DoEatMemoryL( TInt64 aNewSize ) |
|
473 { |
|
474 // check that new size is in valid range |
|
475 if (aNewSize < 0) |
|
476 { |
|
477 aNewSize = 0; |
|
478 } |
|
479 LOGSTRING2("Loadgen::DoEatMemoryL aNewSize = %d", aNewSize ); |
|
480 // set new size |
|
481 if (iAttributes.iSource == EMemoryEatSourceTypeRAM) |
|
482 { |
|
483 TInt err = iEatChunk.Adjust( aNewSize ); |
|
484 } |
|
485 else |
|
486 { |
|
487 HandleEatMemoryL( aNewSize ); |
|
488 } |
|
489 } |
|
490 |
|
491 // -------------------------------------------------------------------------------------------- |
|
492 |
|
493 void CMemoryEatManager::HandleEatMemoryL( TInt64 aNewSize ) |
|
494 { |
|
495 // current size = open file size + full files sizes |
|
496 TInt currentFileSize = 0; |
|
497 User::LeaveIfError( iEatFile.Size( currentFileSize ) ); |
|
498 TInt64 currentSize = currentFileSize + ( ( iFilesCounter - 1 ) * KMaxEatSize ); |
|
499 |
|
500 if ( aNewSize > currentSize ) // increasing |
|
501 { |
|
502 AllocMemoryL( aNewSize ); |
|
503 } |
|
504 else if ( aNewSize < currentSize )//decreasing |
|
505 { |
|
506 FreeMemoryL( aNewSize ); |
|
507 } |
|
508 } |
|
509 |
|
510 // -------------------------------------------------------------------------------------------- |
|
511 void CMemoryEatManager::AllocMemoryL( TInt64 aNewSize ) |
|
512 { |
|
513 LOGSTRING("Loadgen: CMemoryEatManager::AllocMemoryL =>"); |
|
514 // size of the file that remains open |
|
515 TInt64 sizeLeft = aNewSize % KMaxEatSize; |
|
516 // amount of the files that is needed |
|
517 TInt64 filesNeeded = aNewSize / KMaxEatSize; |
|
518 if ( sizeLeft > 0 ) |
|
519 { |
|
520 filesNeeded++; |
|
521 } |
|
522 |
|
523 if ( filesNeeded > iFilesCounter ) |
|
524 { |
|
525 // update current file size to 2 GB |
|
526 User::LeaveIfError( iEatFile.SetSize( KMaxEatSize ) ); |
|
527 // close current file |
|
528 iEatFile.Flush(); |
|
529 iEatFile.Close(); |
|
530 |
|
531 // open new file |
|
532 TFileName eatFileName; |
|
533 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, ++iFilesCounter ); |
|
534 |
|
535 iFs.MkDirAll( eatFileName ); |
|
536 User::LeaveIfError( iEatFile.Replace( iFs, eatFileName, EFileWrite ) ); |
|
537 |
|
538 } |
|
539 User::LeaveIfError( iEatFile.SetSize( sizeLeft ) ); |
|
540 LOGSTRING("Loadgen: CMemoryEatManager::AllocMemoryL <="); |
|
541 } |
|
542 |
|
543 // -------------------------------------------------------------------------------------------- |
|
544 void CMemoryEatManager::FreeMemoryL( TInt64 aNewSize ) |
|
545 { |
|
546 LOGSTRING("Loadgen: CMemoryEatManager::FreeMemoryL =>"); |
|
547 // size of the file that remains open |
|
548 TInt sizeLeft = aNewSize % KMaxEatSize; |
|
549 |
|
550 LOGSTRING2("Loadgen: sizeLeft = %d ", sizeLeft ); |
|
551 // amount of the files that is needed |
|
552 TInt filesNeeded = aNewSize / KMaxEatSize; |
|
553 |
|
554 if ( filesNeeded == 0 ) |
|
555 { |
|
556 filesNeeded = 1; |
|
557 } |
|
558 |
|
559 if ( iFilesCounter > 1 && filesNeeded < iFilesCounter ) |
|
560 { |
|
561 TFileName eatFileName; |
|
562 |
|
563 // close current open file |
|
564 iEatFile.Flush(); |
|
565 iEatFile.Close(); |
|
566 // remove file |
|
567 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, iFilesCounter-- ); |
|
568 iFs.Delete( eatFileName ); |
|
569 |
|
570 // remove files not needed |
|
571 while ( iFilesCounter > filesNeeded ) |
|
572 { |
|
573 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, iFilesCounter-- ); |
|
574 iFs.Delete( eatFileName ); |
|
575 } |
|
576 |
|
577 // open new file |
|
578 eatFileName.Format( KFilePath, 'B'+iAttributes.iSource, iAttributes.iId, iFilesCounter ); |
|
579 User::LeaveIfError( iEatFile.Open( iFs, eatFileName, EFileWrite ) ); |
|
580 } |
|
581 User::LeaveIfError( iEatFile.SetSize( sizeLeft ) ); |
|
582 LOGSTRING("Loadgen: CMemoryEatManager::FreeMemoryL <="); |
|
583 } |
|
584 |
|
585 // -------------------------------------------------------------------------------------------- |
|
586 TInt64 CMemoryEatManager::ReadFreeMemory() |
|
587 { |
|
588 if ( iAttributes.iSource == EMemoryEatSourceTypeRAM ) |
|
589 { |
|
590 TMemoryInfoV1Buf ramMemory; |
|
591 UserHal::MemoryInfo( ramMemory ); // get available RAM |
|
592 return (TInt64)ramMemory().iFreeRamInBytes; |
|
593 } |
|
594 else |
|
595 { |
|
596 TVolumeInfo volumeInfo; |
|
597 iFs.Volume( volumeInfo, iAttributes.iSource + 1 ); // get available disk |
|
598 return volumeInfo.iFree; |
|
599 } |
|
600 } |
|
601 // -------------------------------------------------------------------------------------------- |
|
602 |
|
603 // End of File |