loadgen/src/loadgen_memoryeat.cpp
branchRCL_3
changeset 22 fad26422216a
parent 0 d6fe6244b863
equal deleted inserted replaced
21:b3cee849fa46 22:fad26422216a
       
     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