perfmon/engine/src/perfmon_engine.cpp
branchRCL_3
changeset 22 fad26422216a
parent 21 b3cee849fa46
child 23 f8280f3bfeb7
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 // INCLUDE FILES
       
    18 #include "perfmon_engine.h"
       
    19 #include <coeutils.h>
       
    20 #include <bautils.h>
       
    21 #include <eikenv.h>
       
    22 #include <e32hal.h>
       
    23 #include <u32std.h>
       
    24 #include <s32file.h>
       
    25 #include <akntitle.h> 
       
    26 #include <eikspane.h>
       
    27 #include <aknnotewrappers.h>  
       
    28 _LIT(KDefaultLogFilePath, "c:\\data\\PerfMon.log");
       
    29 
       
    30 const TInt KCalibrationLength = 2;
       
    31 const TInt KMinimumSamplesLength = 16;
       
    32 const TInt KCPUTimeMultiplier = 1000000; // used to avoid TReal conversions
       
    33 
       
    34 const TInt KSettingsDrive = EDriveC;
       
    35 _LIT(KSettingsFileName, "perfmon_settings.ini");
       
    36 
       
    37 // --------------------------------------------------------------------------------------------
       
    38 
       
    39 TInt CPULoadCount(TAny* aInt)
       
    40     {
       
    41     // increase the counter
       
    42     (*(TUint*) aInt)++;
       
    43     return 1;
       
    44     }
       
    45 
       
    46 TInt CPULoadNOPThread(TAny* aParam)
       
    47     {
       
    48     CTrapCleanup* pC = CTrapCleanup::New();
       
    49     CActiveScheduler* pS = new CActiveScheduler;
       
    50     CActiveScheduler::Install(pS);
       
    51 
       
    52     CIdle* idle = CIdle::NewL(CActive::EPriorityLow);
       
    53     TCallBack cb(CPULoadCount, aParam);
       
    54     idle->Start(cb);
       
    55 
       
    56     pS->Start();
       
    57 
       
    58     delete idle;
       
    59     delete pS;
       
    60     delete pC;
       
    61 
       
    62     return 0;
       
    63     }
       
    64 
       
    65 // ===================================== MEMBER FUNCTIONS =====================================
       
    66 
       
    67 CPerfMonEngine::CPerfMonEngine() :
       
    68     CActive(EPriorityUserInput)
       
    69     {
       
    70     }
       
    71 
       
    72 // --------------------------------------------------------------------------------------------
       
    73 
       
    74 void CPerfMonEngine::ConstructL()
       
    75     {
       
    76     iCurrentCPUMode = ECPUModeNotSet;
       
    77     iLogFileInitialized = EFalse;
       
    78 
       
    79     iEnv = CEikonEnv::Static();
       
    80     User::LeaveIfError(iLs.Connect());
       
    81 
       
    82     User::LeaveIfError(iTimer.CreateLocal());
       
    83     CActiveScheduler::Add(this);
       
    84     }
       
    85 
       
    86 // --------------------------------------------------------------------------------------------
       
    87 
       
    88 void CPerfMonEngine::ActivateEngineL()
       
    89     {
       
    90     // load settings
       
    91     TRAP_IGNORE(LoadSettingsL());
       
    92 
       
    93     // create data storages for the samples
       
    94     CreateSamplesDataArrayL();
       
    95 
       
    96     // set default modes
       
    97     HandleSettingsChangeL();
       
    98 
       
    99     // start sampling data immediately (jump to RunL)    
       
   100     iTimer.After(iStatus, 100);
       
   101     SetActive();
       
   102     }
       
   103 
       
   104 // --------------------------------------------------------------------------------------------
       
   105 
       
   106 void CPerfMonEngine::DeActivateEngineL()
       
   107     {
       
   108     Cancel();
       
   109 
       
   110     DeActivateCPUMonitoring();
       
   111 
       
   112     // close log file
       
   113     OpenLogFile(EFalse);
       
   114     }
       
   115 
       
   116 // --------------------------------------------------------------------------------------------
       
   117 
       
   118 CPerfMonEngine::~CPerfMonEngine()
       
   119     {
       
   120     iTimer.Close();
       
   121 
       
   122     // clear data storages
       
   123     if (iSampleEntryArray)
       
   124         {
       
   125         for (TInt i = 0; i < iSampleEntryArray->Count(); i++)
       
   126             {
       
   127             delete iSampleEntryArray->At(i).iSampleDataArray;
       
   128             }
       
   129 
       
   130         delete iSampleEntryArray;
       
   131         }
       
   132 
       
   133     iLs.Close();
       
   134     }
       
   135 
       
   136 // --------------------------------------------------------------------------------------------
       
   137 
       
   138 void CPerfMonEngine::DoCancel()
       
   139     {
       
   140     iTimer.Cancel();
       
   141     }
       
   142 
       
   143 // --------------------------------------------------------------------------------------------
       
   144 
       
   145 void CPerfMonEngine::RunL()
       
   146     {
       
   147     // calculate new values 
       
   148     UpdateSamplesDataL();
       
   149 
       
   150     // log changes
       
   151     AppendLatestSamplesToLogsL();
       
   152 
       
   153     // redraw views
       
   154     SendDrawEventToContainersL();
       
   155 
       
   156     // continue
       
   157     iTimer.After(iStatus, iSettings.iHeartBeat * 1000); // convert from milliseconds to microseconds
       
   158     SetActive();
       
   159     }
       
   160 
       
   161 // --------------------------------------------------------------------------------------------
       
   162 
       
   163 void CPerfMonEngine::HandleSettingsChangeL()
       
   164     {
       
   165     // set priority of the thread
       
   166     RThread().SetPriority(SettingItemToThreadPriority(iSettings.iPriority));
       
   167 
       
   168     // init cpu monitor if setting has been changed
       
   169     if (iCurrentCPUMode != iSettings.iCPUMode)
       
   170         {
       
   171         DeActivateCPUMonitoring();
       
   172         ActivateCPUMonitoringL();
       
   173         }
       
   174 
       
   175     // close log file
       
   176     OpenLogFile(EFalse);
       
   177 
       
   178     // enable log file
       
   179     if (iSettings.iLoggingEnabled && (iSettings.iLoggingMode
       
   180             == ELoggingModeLogFile || iSettings.iLoggingMode
       
   181             == ELoggingModeRDebugLogFile))
       
   182         OpenLogFile(ETrue);
       
   183     }
       
   184 
       
   185 // --------------------------------------------------------------------------------------------
       
   186 
       
   187 void CPerfMonEngine::EnableLogging(TBool aEnable)
       
   188     {
       
   189     if (aEnable)
       
   190         {
       
   191         if (iSettings.iLoggingMode == ELoggingModeLogFile
       
   192                 || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   193             OpenLogFile(ETrue);
       
   194 
       
   195         iSettings.iLoggingEnabled = ETrue;
       
   196         }
       
   197     else // disable
       
   198         {
       
   199         iSettings.iLoggingEnabled = EFalse;
       
   200         OpenLogFile(EFalse);
       
   201         }
       
   202     }
       
   203 
       
   204 // --------------------------------------------------------------------------------------------
       
   205 
       
   206 void CPerfMonEngine::OpenLogFile(TBool aOpen)
       
   207     {
       
   208     // open log file for writing
       
   209     if (aOpen)
       
   210         {
       
   211         if (!iLogFileInitialized)
       
   212             {
       
   213             TInt err(KErrNone);
       
   214 
       
   215             // open the log file for writing
       
   216             if (iLogFile.Open(iEnv->FsSession(), iSettings.iLoggingFilePath,
       
   217                     EFileWrite) != KErrNone)
       
   218                 {
       
   219                 iEnv->FsSession().MkDirAll(iSettings.iLoggingFilePath);
       
   220                 err = iLogFile.Replace(iEnv->FsSession(),
       
   221                         iSettings.iLoggingFilePath, EFileWrite);
       
   222                 }
       
   223             else
       
   224                 {
       
   225                 // file opens correctly, seek to the end
       
   226                 TInt fileSize = 0;
       
   227                 iLogFile.Size(fileSize);
       
   228                 err = iLogFile.Seek(ESeekCurrent, fileSize);
       
   229                 }
       
   230 
       
   231             if (err == KErrNone)
       
   232                 {
       
   233                 iLogFileInitialized = ETrue;
       
   234                 }
       
   235             else
       
   236                 {
       
   237                 // show error
       
   238                 CAknErrorNote* note = new (ELeave) CAknErrorNote();
       
   239                 note->ExecuteLD(_L("Unable to create log file, check settings"));
       
   240                 }
       
   241             }
       
   242         }
       
   243 
       
   244     // close handle to log file
       
   245     else
       
   246         {
       
   247         if (iLogFileInitialized)
       
   248             {
       
   249             iLogFile.Flush();
       
   250             iLogFile.Close();
       
   251 
       
   252             iLogFileInitialized = EFalse;
       
   253             }
       
   254         }
       
   255     }
       
   256 
       
   257 // --------------------------------------------------------------------------------------------
       
   258 
       
   259 void CPerfMonEngine::ActivateCPUMonitoringL()
       
   260     {
       
   261     // reset counter variables
       
   262     iCPULoadCalibrating = ETrue;
       
   263     iCPULoadCalibrationCounter = 0;
       
   264     iCPULoadMaxValue = 999999999;
       
   265     iCPULoadPreviousValue = 1;
       
   266     iCPULoadCounter = 0;
       
   267 
       
   268     // use null thread is cpu time is supported and the setting is on
       
   269     if (CPUTimeSupported() && iSettings.iCPUMode == ECPUModeCPUTime)
       
   270         {
       
   271         // try to open handle to null thread
       
   272         if (OpenHandleToNullThread())
       
   273             {
       
   274             // handle is open, get initial value
       
   275             TTimeIntervalMicroSeconds time;
       
   276             iNullThread.GetCpuTime(time);
       
   277             iCPULoadPreviousValue = time.Int64();
       
   278             iPreviousTime.HomeTime();
       
   279 
       
   280             iCurrentCPUMode = ECPUModeCPUTime;
       
   281             return; // cpu time is succesfully in use           
       
   282             }
       
   283         }
       
   284 
       
   285     // otherwise use normal sampling with nops    
       
   286     iCurrentCPUMode = ECPUModeNotSet;
       
   287 
       
   288     // show a warning if cpu time cannot be taken in use
       
   289     if (iSettings.iCPUMode == ECPUModeCPUTime)
       
   290         {
       
   291         CAknInformationNote* note = new (ELeave) CAknInformationNote();
       
   292         note->ExecuteLD(
       
   293                 _L("CPU Time not supported in this system, using NOPs sampling"));
       
   294         }
       
   295 
       
   296     // create a thread for CPU load monitoring
       
   297     User::LeaveIfError(iCPULoadThread.Create(_L("PerfMonCPULoad"),
       
   298             CPULoadNOPThread, 0x1000, 0x1000, 0x100000, &iCPULoadCounter));
       
   299     iCPULoadThread.SetPriority(EPriorityAbsoluteVeryLow);
       
   300     iCPULoadThread.Resume();
       
   301 
       
   302     iCurrentCPUMode = ECPUModeNOPs; // NOPs taken succesfully in use
       
   303     }
       
   304 
       
   305 // --------------------------------------------------------------------------------------------
       
   306 
       
   307 TBool CPerfMonEngine::OpenHandleToNullThread()
       
   308     {
       
   309     // find the kernel process and then the null thread
       
   310     TFindProcess fp(_L("ekern.exe*"));
       
   311 
       
   312     TFullName kernelName;
       
   313     if (fp.Next(kernelName) == KErrNone)
       
   314         {
       
   315         // process found, append null thread identifier
       
   316         kernelName.Append(_L("::Null"));
       
   317 
       
   318         // find the thread
       
   319         TFindThread ft(kernelName);
       
   320 
       
   321         TFullName threadName;
       
   322         if (ft.Next(threadName) == KErrNone)
       
   323             {
       
   324             // open instance to the thread
       
   325             if (iNullThread.Open(threadName) != KErrNone)
       
   326                 return EFalse;
       
   327             }
       
   328         }
       
   329 
       
   330     // process not found
       
   331     else
       
   332         return EFalse;
       
   333 
       
   334     // success!
       
   335     return ETrue;
       
   336     }
       
   337 
       
   338 // --------------------------------------------------------------------------------------------
       
   339 
       
   340 void CPerfMonEngine::DeActivateCPUMonitoring()
       
   341     {
       
   342     if (iCurrentCPUMode == ECPUModeCPUTime)
       
   343         {
       
   344         iNullThread.Close();
       
   345         }
       
   346 
       
   347     else if (iCurrentCPUMode == ECPUModeNOPs)
       
   348         {
       
   349         // kill the cpu load thread
       
   350         iCPULoadThread.Kill(0);
       
   351         iCPULoadThread.Close();
       
   352         }
       
   353     }
       
   354 
       
   355 // --------------------------------------------------------------------------------------------
       
   356 
       
   357 TBool CPerfMonEngine::CPUTimeSupported()
       
   358     {
       
   359     TTimeIntervalMicroSeconds time;
       
   360     TInt err = RThread().GetCpuTime(time);
       
   361 
       
   362     if (err == KErrNone && time.Int64() > 0)
       
   363         return ETrue;
       
   364     else
       
   365         return EFalse;
       
   366     }
       
   367 
       
   368 // --------------------------------------------------------------------------------------------
       
   369 
       
   370 TThreadPriority CPerfMonEngine::SettingItemToThreadPriority(TInt aIndex)
       
   371     {
       
   372     TThreadPriority threadPriority = EPriorityNull;
       
   373 
       
   374     switch (aIndex)
       
   375         {
       
   376         case EThreadPriorityTypeMuchLess:
       
   377             {
       
   378             threadPriority = EPriorityMuchLess;
       
   379             break;
       
   380             }
       
   381         case EThreadPriorityTypeLess:
       
   382             {
       
   383             threadPriority = EPriorityLess;
       
   384             break;
       
   385             }
       
   386         case EThreadPriorityTypeNormal:
       
   387             {
       
   388             threadPriority = EPriorityNormal;
       
   389             break;
       
   390             }
       
   391         case EThreadPriorityTypeMore:
       
   392             {
       
   393             threadPriority = EPriorityMore;
       
   394             break;
       
   395             }
       
   396         case EThreadPriorityTypeMuchMore:
       
   397             {
       
   398             threadPriority = EPriorityMuchMore;
       
   399             break;
       
   400             }
       
   401         case EThreadPriorityTypeRealTime:
       
   402             {
       
   403             threadPriority = EPriorityRealTime;
       
   404             break;
       
   405             }
       
   406         case EThreadPriorityTypeAbsoluteVeryLow:
       
   407             {
       
   408             threadPriority = EPriorityAbsoluteVeryLow;
       
   409             break;
       
   410             }
       
   411         case EThreadPriorityTypeAbsoluteLow:
       
   412             {
       
   413             threadPriority = EPriorityAbsoluteLow;
       
   414             break;
       
   415             }
       
   416         case EThreadPriorityTypeAbsoluteBackground:
       
   417             {
       
   418             threadPriority = EPriorityAbsoluteBackground;
       
   419             break;
       
   420             }
       
   421         case EThreadPriorityTypeAbsoluteForeground:
       
   422             {
       
   423             threadPriority = EPriorityAbsoluteForeground;
       
   424             break;
       
   425             }
       
   426         case EThreadPriorityTypeAbsoluteHigh:
       
   427             {
       
   428             threadPriority = EPriorityAbsoluteHigh;
       
   429             break;
       
   430             }
       
   431 
       
   432         default:
       
   433             {
       
   434             User::Panic(_L("Wrong tp index"), 276);
       
   435             break;
       
   436             }
       
   437         }
       
   438 
       
   439     return threadPriority;
       
   440     }
       
   441 
       
   442 // --------------------------------------------------------------------------------------------
       
   443 
       
   444 void CPerfMonEngine::CreateSamplesDataArrayL()
       
   445     {
       
   446     TInt
       
   447             maxSamples =
       
   448                     iSettings.iMaxSamples >= KMinimumSamplesLength ? iSettings.iMaxSamples
       
   449                             : KMinimumSamplesLength;
       
   450 
       
   451     // create the data structure to store all samples
       
   452     iSampleEntryArray = new (ELeave) CSampleEntryArray(16);
       
   453 
       
   454     // add all source entries
       
   455     for (TInt i = 0; i < ESourcesLength; i++)
       
   456         {
       
   457         TSampleEntry newSampleEntry;
       
   458 
       
   459         if (i == ESourceCPU)
       
   460             {
       
   461             newSampleEntry.iDescription.Copy(_L("CPU"));
       
   462             newSampleEntry.iUnitTypeShort.Copy(KNullDesC);
       
   463             newSampleEntry.iUnitTypeLong.Copy(KNullDesC);
       
   464             newSampleEntry.iDriveNumber = -1;
       
   465             newSampleEntry.iGraphColor = KRgbYellow;
       
   466             }
       
   467 
       
   468         else if (i == ESourceRAM)
       
   469             {
       
   470             newSampleEntry.iDescription.Copy(_L("RAM"));
       
   471             newSampleEntry.iUnitTypeShort.Copy(_L("b"));
       
   472             newSampleEntry.iUnitTypeLong.Copy(_L("bytes"));
       
   473             newSampleEntry.iDriveNumber = -1;
       
   474             newSampleEntry.iGraphColor = KRgbGreen;
       
   475             }
       
   476 
       
   477         else //drives
       
   478             {
       
   479             TChar driveLetter = 'C' + i - ESourceC; // C is the first drive
       
   480 
       
   481             newSampleEntry.iDescription.Append(driveLetter);
       
   482             newSampleEntry.iDescription.Append(_L(":"));
       
   483             newSampleEntry.iUnitTypeShort.Copy(_L("b"));
       
   484             newSampleEntry.iUnitTypeLong.Copy(_L("bytes"));
       
   485 
       
   486             iEnv->FsSession().CharToDrive(driveLetter,
       
   487                     newSampleEntry.iDriveNumber);
       
   488 
       
   489             newSampleEntry.iGraphColor = KRgbCyan;
       
   490             newSampleEntry.iGraphColor.SetGreen(255 - (i - ESourceC) * 30);
       
   491             newSampleEntry.iGraphColor.SetRed(i * 30);
       
   492             }
       
   493 
       
   494         newSampleEntry.iSampleDataArray = new (ELeave) CSampleDataArray(
       
   495                 maxSamples);
       
   496 
       
   497         iSampleEntryArray->AppendL(newSampleEntry);
       
   498         }
       
   499 
       
   500     // save current time as start time
       
   501     iStartTime.HomeTime();
       
   502     }
       
   503 
       
   504 // --------------------------------------------------------------------------------------------
       
   505 
       
   506 void CPerfMonEngine::UpdateSamplesDataL()
       
   507     {
       
   508     // reset inactivity timers
       
   509     if (iSettings.iKeepBacklightOn)
       
   510         User::ResetInactivityTime();
       
   511 
       
   512     // get current time
       
   513     TTime currentTime;
       
   514     currentTime.HomeTime();
       
   515 
       
   516     // calculate time difference
       
   517     TTimeIntervalMicroSeconds timeDeltaFromPreviousSample =
       
   518             currentTime.MicroSecondsFrom(iPreviousTime);
       
   519 
       
   520     // remember current time as previous
       
   521     iPreviousTime = currentTime;
       
   522 
       
   523     // get CPU
       
   524     TInt64 cpuLoadDelta(0);
       
   525     TInt64 cpuLoadFree(0);
       
   526     TInt64 cpuLoadSize(0);
       
   527     TInt64 currentCPUValue(0);
       
   528 
       
   529     if (iCurrentCPUMode == ECPUModeCPUTime || iCurrentCPUMode == ECPUModeNOPs)
       
   530         {
       
   531         if (iCurrentCPUMode == ECPUModeCPUTime)
       
   532             {
       
   533             TTimeIntervalMicroSeconds time;
       
   534             iNullThread.GetCpuTime(time);
       
   535             currentCPUValue = time.Int64();
       
   536             }
       
   537         else if (iCurrentCPUMode == ECPUModeNOPs)
       
   538             {
       
   539             currentCPUValue = iCPULoadCounter;
       
   540             }
       
   541 
       
   542         // get delta and store the previous value
       
   543         cpuLoadDelta = currentCPUValue - iCPULoadPreviousValue;
       
   544         iCPULoadPreviousValue = currentCPUValue;
       
   545 
       
   546         // velocity = distance / time
       
   547         cpuLoadFree = cpuLoadDelta * KCPUTimeMultiplier
       
   548                 / timeDeltaFromPreviousSample.Int64();
       
   549 
       
   550         // detect maximum value
       
   551         if (cpuLoadFree > iCPULoadMaxValue)
       
   552             iCPULoadMaxValue = cpuLoadFree;
       
   553 
       
   554         // check calibration status      
       
   555         if (iCPULoadCalibrating)
       
   556             {
       
   557             iCPULoadCalibrationCounter++;
       
   558             cpuLoadSize = cpuLoadFree;
       
   559 
       
   560             // check if need to calibrate anymore
       
   561             if (iCPULoadCalibrationCounter > KCalibrationLength)
       
   562                 {
       
   563                 iCPULoadCalibrating = EFalse;
       
   564 
       
   565                 // from the samples, get the minimum value, and let it be the max value 
       
   566                 for (TInt i = 0; i
       
   567                         < iSampleEntryArray->At(0).iSampleDataArray->Count(); i++)
       
   568                     {
       
   569                     TInt64 newCPULoadMaxValue = iCPULoadMaxValue;
       
   570 
       
   571                     if (iSampleEntryArray->At(0).iSampleDataArray->At(i).iFree
       
   572                             < newCPULoadMaxValue)
       
   573                         {
       
   574                         newCPULoadMaxValue
       
   575                                 = iSampleEntryArray->At(0).iSampleDataArray->At(
       
   576                                         i).iFree;
       
   577                         }
       
   578 
       
   579                     iCPULoadMaxValue = newCPULoadMaxValue;
       
   580                     }
       
   581 
       
   582                 // adjust priority of the poller thread
       
   583                 if (iCurrentCPUMode == ECPUModeNOPs)
       
   584                     {
       
   585                     iCPULoadThread.SetPriority(EPriorityAbsoluteVeryLow);
       
   586                     }
       
   587                 }
       
   588 
       
   589             }
       
   590         else
       
   591             {
       
   592             cpuLoadSize = iCPULoadMaxValue;
       
   593             }
       
   594         }
       
   595 
       
   596     // save cpu sample data    
       
   597     TSampleData cpuSample;
       
   598     cpuSample.iFree = cpuLoadFree;
       
   599     cpuSample.iSize = cpuLoadSize;
       
   600     cpuSample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   601 
       
   602     iSampleEntryArray->At(0).iSampleDataArray->InsertL(0, cpuSample);
       
   603 
       
   604     // get ram memory
       
   605     TMemoryInfoV1Buf ramMemory;
       
   606     UserHal::MemoryInfo(ramMemory);
       
   607 
       
   608     TSampleData memorySample;
       
   609     memorySample.iFree = ramMemory().iFreeRamInBytes;
       
   610     memorySample.iSize = ramMemory().iMaxFreeRamInBytes;
       
   611     memorySample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   612 
       
   613     iSampleEntryArray->At(1).iSampleDataArray->InsertL(0, memorySample);
       
   614 
       
   615     // all drives
       
   616     for (TInt i = 2; i < iSampleEntryArray->Count(); i++)
       
   617         {
       
   618         TSampleData driveSample;
       
   619 
       
   620         // get volume info from RFs
       
   621         TVolumeInfo volumeInfo;
       
   622         if (iEnv->FsSession().Volume(volumeInfo,
       
   623                 iSampleEntryArray->At(i).iDriveNumber) == KErrNone)
       
   624             {
       
   625             driveSample.iFree = volumeInfo.iFree;
       
   626             driveSample.iSize = volumeInfo.iSize;
       
   627             }
       
   628         else
       
   629             {
       
   630             driveSample.iFree = 0;
       
   631             driveSample.iSize = 0;
       
   632             }
       
   633 
       
   634         driveSample.iTimeFromStart = currentTime.MicroSecondsFrom(iStartTime);
       
   635 
       
   636         iSampleEntryArray->At(i).iSampleDataArray->InsertL(0, driveSample);
       
   637         }
       
   638 
       
   639     // compress sample data arrays to save memory
       
   640     TInt curLength(iSampleEntryArray->At(0).iSampleDataArray->Count());
       
   641 
       
   642     TInt
       
   643             maxSamples =
       
   644                     iSettings.iMaxSamples >= KMinimumSamplesLength ? iSettings.iMaxSamples
       
   645                             : KMinimumSamplesLength;
       
   646 
       
   647     if (curLength > maxSamples && curLength % 5 == 0)
       
   648         {
       
   649         for (TInt i = 0; i < iSampleEntryArray->Count(); i++)
       
   650             {
       
   651             iSampleEntryArray->At(i).iSampleDataArray->ResizeL(maxSamples); // looses old samples
       
   652             iSampleEntryArray->At(i).iSampleDataArray->Compress();
       
   653             }
       
   654         }
       
   655     }
       
   656 
       
   657 // --------------------------------------------------------------------------------------------
       
   658 
       
   659 void CPerfMonEngine::AppendLatestSamplesToLogsL()
       
   660     {
       
   661     if (iSettings.iLoggingEnabled && SampleEntryArray())
       
   662         {
       
   663         // loop all sources
       
   664         for (TInt i = 0; i < SampleEntryArray()->Count(); i++)
       
   665             {
       
   666             // check if this setting has been enabled and it has some data
       
   667             if (iSettings.iLoggingSources.iSrcEnabled[i]
       
   668                     && SampleEntryArray()->At(i).iSampleDataArray->Count() > 0)
       
   669                 {
       
   670                 // get current sample
       
   671                 TSampleData& currentSample =
       
   672                         SampleEntryArray()->At(i).iSampleDataArray->At(0);
       
   673 
       
   674                 TBuf<128> buf;
       
   675                 buf.Append(_L("PERFMON;"));
       
   676                 buf.Append(SampleEntryArray()->At(i).iDescription);
       
   677                 buf.Append(_L(";"));
       
   678                 buf.AppendNum(currentSample.iTimeFromStart.Int64());
       
   679                 buf.Append(_L(";"));
       
   680                 buf.AppendNum(currentSample.iFree);
       
   681                 buf.Append(_L(";"));
       
   682                 buf.AppendNum(currentSample.iSize);
       
   683 
       
   684                 // print to RDebug
       
   685                 if (iSettings.iLoggingMode == ELoggingModeRDebug
       
   686                         || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   687                     {
       
   688                     RDebug::Print(buf);
       
   689                     }
       
   690 
       
   691                 // print to log file
       
   692                 if (iSettings.iLoggingMode == ELoggingModeLogFile
       
   693                         || iSettings.iLoggingMode == ELoggingModeRDebugLogFile)
       
   694                     {
       
   695                     buf.Append(_L("\r\n"));
       
   696 
       
   697                     TBuf8<128> buf8;
       
   698                     buf8.Copy(buf);
       
   699 
       
   700                     iLogFile.Write(buf8);
       
   701                     }
       
   702                 }
       
   703             }
       
   704         }
       
   705     }
       
   706 
       
   707 void CPerfMonEngine::LoadSettingsL()
       
   708     {
       
   709     // set defaults
       
   710     iSettings.iHeartBeat = 600;
       
   711     iSettings.iMaxSamples = 64;
       
   712     iSettings.iPriority = EThreadPriorityTypeNormal;
       
   713     iSettings.iCPUMode = ECPUModeCPUTime;
       
   714     iSettings.iKeepBacklightOn = ETrue;
       
   715 
       
   716     iSettings.iDataPopupVisibility = EDataPopupVisbilityAlwaysOn;
       
   717     // TODO: remove the next line once data popup is working
       
   718     iSettings.iDataPopupVisibility = EDataPopupVisbilityAlwaysAlwaysOff;
       
   719     iSettings.iDataPopupLocation = EDataPopupLocationTopRight;
       
   720     iSettings.iDataPopupSources.SetDefaults1();
       
   721 
       
   722     iSettings.iGraphsVerticalBarPeriod = 5;
       
   723     iSettings.iGraphsSources.SetDefaults2();
       
   724 
       
   725     iSettings.iLoggingMode = ELoggingModeRDebug;
       
   726     iSettings.iLoggingFilePath.Copy(KDefaultLogFilePath);
       
   727     iSettings.iLoggingSources.SetDefaults2();
       
   728 
       
   729     iSettings.iLoggingEnabled = EFalse;
       
   730 
       
   731     // make sure that the private path of this app in c-drive exists
       
   732     iEnv->FsSession().CreatePrivatePath(KSettingsDrive); // c:\\private\\20011385\\
       
   733     
       
   734     // handle settings always in the private directory 
       
   735     if (iEnv->FsSession().SetSessionToPrivate(KSettingsDrive) == KErrNone)
       
   736         {
       
   737         const TUid KUidPerfMon =
       
   738             {
       
   739             0x20011385
       
   740             };
       
   741         // open or create a dictionary file store
       
   742         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(
       
   743                 iEnv->FsSession(), KSettingsFileName, KUidPerfMon);
       
   744 
       
   745         LoadDFSValueL(settingsStore, KPMSettingHeartBeat, iSettings.iHeartBeat);
       
   746         LoadDFSValueL(settingsStore, KPMSettingMaxSamples,
       
   747                 iSettings.iMaxSamples);
       
   748         LoadDFSValueL(settingsStore, KPMSettingPriority, iSettings.iPriority);
       
   749         
       
   750         LoadDFSValueL(settingsStore, KPMSettingCPUMode, iSettings.iCPUMode);
       
   751         
       
   752         LoadDFSValueL(settingsStore, KPMSettingKeepBackLightOn,
       
   753                 iSettings.iKeepBacklightOn);
       
   754 
       
   755         LoadDFSValueL(settingsStore, KPMSettingDataPopupVisbility,
       
   756                 iSettings.iDataPopupVisibility);
       
   757         LoadDFSValueL(settingsStore, KPMSettingDataPopupLocation,
       
   758                 iSettings.iDataPopupLocation);
       
   759         LoadDFSValueL(settingsStore, KPMSettingDataPopupSources,
       
   760                 iSettings.iDataPopupSources);
       
   761 
       
   762         LoadDFSValueL(settingsStore, KPMSettingGraphsVerticalBarPeriod,
       
   763                 iSettings.iGraphsVerticalBarPeriod);
       
   764         LoadDFSValueL(settingsStore, KPMSettingGraphsSources,
       
   765                 iSettings.iGraphsSources);
       
   766 
       
   767         LoadDFSValueL(settingsStore, KPMSettingLoggingMode,
       
   768                 iSettings.iLoggingMode);
       
   769         LoadDFSValueL(settingsStore, KPMSettingLoggingFilePath,
       
   770                 iSettings.iLoggingFilePath);
       
   771         LoadDFSValueL(settingsStore, KPMSettingLoggingSources,
       
   772                 iSettings.iLoggingSources);
       
   773 
       
   774         CleanupStack::PopAndDestroy(); // settingsStore         
       
   775         }
       
   776     }
       
   777 
       
   778 // --------------------------------------------------------------------------------------------
       
   779 
       
   780 void CPerfMonEngine::SaveSettingsL()
       
   781     {
       
   782     // handle settings always in c:\\private\\20011385\\
       
   783     if (iEnv->FsSession().SetSessionToPrivate( KSettingsDrive ) == KErrNone)
       
   784         {
       
   785         // delete existing store to make sure that it is clean and not eg corrupted
       
   786         if (BaflUtils::FileExists(iEnv->FsSession(), KSettingsFileName))
       
   787             {
       
   788             iEnv->FsSession().Delete(KSettingsFileName);
       
   789             }
       
   790 
       
   791         const TUid KUidPerfMon =
       
   792             {
       
   793             0x20011385
       
   794             };
       
   795         // create a dictionary file store
       
   796         CDictionaryFileStore* settingsStore = CDictionaryFileStore::OpenLC(
       
   797                 iEnv->FsSession(), KSettingsFileName, KUidPerfMon);
       
   798 
       
   799         SaveDFSValueL(settingsStore, KPMSettingHeartBeat, iSettings.iHeartBeat);
       
   800         SaveDFSValueL(settingsStore, KPMSettingMaxSamples,
       
   801                 iSettings.iMaxSamples);
       
   802         SaveDFSValueL(settingsStore, KPMSettingPriority, iSettings.iPriority);
       
   803         SaveDFSValueL(settingsStore, KPMSettingCPUMode, iSettings.iCPUMode);
       
   804         SaveDFSValueL(settingsStore, KPMSettingKeepBackLightOn,
       
   805                 iSettings.iKeepBacklightOn);
       
   806 
       
   807         SaveDFSValueL(settingsStore, KPMSettingDataPopupVisbility,
       
   808                 iSettings.iDataPopupVisibility);
       
   809         SaveDFSValueL(settingsStore, KPMSettingDataPopupLocation,
       
   810                 iSettings.iDataPopupLocation);
       
   811         SaveDFSValueL(settingsStore, KPMSettingDataPopupSources,
       
   812                 iSettings.iDataPopupSources);
       
   813 
       
   814         SaveDFSValueL(settingsStore, KPMSettingGraphsVerticalBarPeriod,
       
   815                 iSettings.iGraphsVerticalBarPeriod);
       
   816         SaveDFSValueL(settingsStore, KPMSettingGraphsSources,
       
   817                 iSettings.iGraphsSources);
       
   818 
       
   819         SaveDFSValueL(settingsStore, KPMSettingLoggingMode,
       
   820                 iSettings.iLoggingMode);
       
   821         SaveDFSValueL(settingsStore, KPMSettingLoggingFilePath,
       
   822                 iSettings.iLoggingFilePath);
       
   823         SaveDFSValueL(settingsStore, KPMSettingLoggingSources,
       
   824                 iSettings.iLoggingSources);
       
   825 
       
   826         settingsStore->CommitL();
       
   827         CleanupStack::PopAndDestroy(); // settingsStore             
       
   828         }
       
   829     }
       
   830 
       
   831 // ---------------------------------------------------------------------------
       
   832 
       
   833 void CPerfMonEngine::LoadDFSValueL(CDictionaryFileStore* aDicFS,
       
   834         const TUid& aUid, TInt& aValue)
       
   835     {
       
   836     if (aDicFS->IsPresentL(aUid))
       
   837         {
       
   838         RDictionaryReadStream in;
       
   839         in.OpenLC(*aDicFS, aUid);
       
   840         aValue = in.ReadInt16L();
       
   841         CleanupStack::PopAndDestroy(); // in        
       
   842         }
       
   843     }
       
   844 
       
   845 // ---------------------------------------------------------------------------
       
   846 
       
   847 void CPerfMonEngine::LoadDFSValueL(CDictionaryFileStore* aDicFS,
       
   848         const TUid& aUid, TDes& aValue)
       
   849     {
       
   850     if (aDicFS->IsPresentL(aUid))
       
   851         {
       
   852         RDictionaryReadStream in;
       
   853         in.OpenLC(*aDicFS, aUid);
       
   854         TInt bufLength = in.ReadInt16L(); // get length of descriptor
       
   855         in.ReadL(aValue, bufLength); // get the descriptor itself
       
   856         CleanupStack::PopAndDestroy(); // in
       
   857         }
       
   858     }
       
   859 
       
   860 // ---------------------------------------------------------------------------
       
   861 
       
   862 void CPerfMonEngine::LoadDFSValueL(CDictionaryFileStore* aDicFS,
       
   863         const TUid& aUid, TPerfMonSources& aValue)
       
   864     {
       
   865     if (aDicFS->IsPresentL(aUid))
       
   866         {
       
   867         RDictionaryReadStream in;
       
   868         in.OpenLC(*aDicFS, aUid);
       
   869         TInt bufLength = in.ReadInt16L(); // get length of the array
       
   870 
       
   871         if (bufLength < 0 || bufLength > ESourcesLength) // check for validaty
       
   872             User::Leave(KErrNotSupported);
       
   873 
       
   874         for (TInt i = 0; i < bufLength; i++) // get all items
       
   875             aValue.iSrcEnabled[i] = in.ReadInt16L();
       
   876 
       
   877         CleanupStack::PopAndDestroy(); // in
       
   878         }
       
   879     }
       
   880 
       
   881 // ---------------------------------------------------------------------------
       
   882 
       
   883 void CPerfMonEngine::SaveDFSValueL(CDictionaryFileStore* aDicFS,
       
   884         const TUid& aUid, const TInt& aValue)
       
   885     {
       
   886     RDictionaryWriteStream out;
       
   887     out.AssignLC(*aDicFS, aUid);
       
   888     out.WriteInt16L(aValue);
       
   889     out.CommitL();
       
   890     CleanupStack::PopAndDestroy(); // out
       
   891     }
       
   892 
       
   893 // ---------------------------------------------------------------------------
       
   894 
       
   895 void CPerfMonEngine::SaveDFSValueL(CDictionaryFileStore* aDicFS,
       
   896         const TUid& aUid, const TDes& aValue)
       
   897     {
       
   898     RDictionaryWriteStream out;
       
   899     out.AssignLC(*aDicFS, aUid);
       
   900     out.WriteInt16L(aValue.Length()); // write length of the descriptor
       
   901     out.WriteL(aValue, aValue.Length()); // write the descriptor itself
       
   902     out.CommitL();
       
   903     CleanupStack::PopAndDestroy(); // out
       
   904     }
       
   905 
       
   906 // ---------------------------------------------------------------------------
       
   907 
       
   908 void CPerfMonEngine::SaveDFSValueL(CDictionaryFileStore* aDicFS,
       
   909         const TUid& aUid, const TPerfMonSources& aValue)
       
   910     {
       
   911     RDictionaryWriteStream out;
       
   912     out.AssignLC(*aDicFS, aUid);
       
   913 
       
   914     out.WriteInt16L(ESourcesLength); // write length of the array
       
   915 
       
   916     for (TInt i = 0; i < ESourcesLength; i++) // write all items
       
   917         out.WriteInt16L(aValue.iSrcEnabled[i]);
       
   918 
       
   919     out.CommitL();
       
   920     CleanupStack::PopAndDestroy(); // out
       
   921     }
       
   922 
       
   923 // ---------------------------------------------------------------------------
       
   924 
       
   925 // End of File