piprofiler/plugins/GeneralsPlugin/src/MemoryEventHandler.cpp
branchRCL_3
changeset 13 da2cedce4920
equal deleted inserted replaced
12:d27dfa8884ad 13:da2cedce4920
       
     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 #include <e32def.h>
       
    19 #include <e32cmn.h>
       
    20 #include <arm.h>
       
    21 #include <kernel.h>
       
    22 #include <kern_priv.h>
       
    23 #include <nk_trace.h>
       
    24 
       
    25 #include "MemoryEventHandler.h"
       
    26 
       
    27 
       
    28 DMemoryEventHandler::DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer)
       
    29     :   DKernelEventHandler(EventHandler, this), 
       
    30         iSampleBuffer(aSampleBuffer), 
       
    31         iSampleDescriptor(&(this->iSample[1]),0,256)
       
    32     {
       
    33 //    Kern::Printf("DMemoryEventHandler::DMemoryEventHandler()");
       
    34     iCount = 0;
       
    35     iPreviousCount = 0;
       
    36     }
       
    37 
       
    38 
       
    39 TInt DMemoryEventHandler::Create()
       
    40     {
       
    41 //    Kern::Printf("DMemoryEventHandler::Create()");
       
    42 
       
    43     TInt err(Kern::MutexCreate(iLock, _L("MemoryEventHandlerLock"), KMutexOrdGeneral0));
       
    44     if (err != KErrNone)
       
    45         return err;
       
    46     
       
    47     return Add();
       
    48     }
       
    49 
       
    50 
       
    51 DMemoryEventHandler::~DMemoryEventHandler()
       
    52     {
       
    53 //    Kern::Printf("DMemoryEventHandler::~DMemoryEventHandler()");
       
    54 
       
    55     if (iLock)
       
    56         iLock->Close(NULL);
       
    57        
       
    58     }
       
    59 
       
    60 
       
    61 TInt DMemoryEventHandler::Start()
       
    62     {
       
    63 //    Kern::Printf("DMemoryEventHandler::Start()");
       
    64 
       
    65     iTracking = ETrue;
       
    66     return KErrNone;
       
    67     }
       
    68 
       
    69 
       
    70 TInt DMemoryEventHandler::Stop()
       
    71     {
       
    72 //    Kern::Printf("DMemoryEventHandler::Stop()");
       
    73 
       
    74     iTracking = EFalse;
       
    75     return KErrNone;
       
    76     }
       
    77 
       
    78 TBool DMemoryEventHandler::SampleNeeded()
       
    79     {
       
    80     LOGTEXT("DMemoryEventHandler::SampleNeeded()");
       
    81     
       
    82     // increase the coutner by one on each round
       
    83     iCount++;
       
    84     
       
    85     // check if event handler was not running
       
    86 //    if(!iTracking)
       
    87 //        return false; // return false
       
    88     
       
    89     return true;
       
    90     }
       
    91 
       
    92 
       
    93 TUint DMemoryEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis)
       
    94     {
       
    95     return ((DMemoryEventHandler*)aThis)->HandleEvent(aType, a1, a2);
       
    96     }
       
    97 
       
    98 
       
    99 
       
   100 TUint DMemoryEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
       
   101     {
       
   102     // debug
       
   103 //    Kern::Printf("New kernel event received, %d", aType);
       
   104     
       
   105     if (iTracking/* && iCount != iPreviousCount*/)
       
   106         {
       
   107 //        iPreviousCount = iCount;
       
   108         iCounters[aType]++;
       
   109         switch (aType)
       
   110             {
       
   111             // capture only chunk creation, updates and destroyal
       
   112             case EEventNewChunk:
       
   113                 {
       
   114                 DChunk* chunk = (DChunk*)a1;
       
   115                 HandleAddChunk(chunk);
       
   116                 break;
       
   117                 }
       
   118             case EEventUpdateChunk:   
       
   119                 HandleUpdateChunk((DChunk*)a1);
       
   120                 break;
       
   121             case EEventDeleteChunk:      
       
   122                 HandleDeleteChunk((DChunk*)a1);
       
   123                 break;
       
   124 //            case EEventAddProcess:
       
   125 //                Kern::Printf("Process added: 0x%08x", (DProcess*)a1);
       
   126 //                break;
       
   127 //            case EEventUpdateProcess:
       
   128 //                Kern::Printf("DProcess updated: 0x%08x", (DProcess*)a1);
       
   129 //                break;
       
   130 //            case EEventRemoveProcess:
       
   131 //                Kern::Printf("DProcess removed: 0x%08x", (DProcess*)a1);
       
   132 //                break;
       
   133 //            case EEventAddCodeSeg:
       
   134 //                Kern::Printf("DCodeSeg added: 0x%08x", (DCodeSeg*)a1);
       
   135 //                break;
       
   136 //            case EEventRemoveCodeSeg:
       
   137 //                Kern::Printf("DCodeSeg deleted: 0x%08x", (DCodeSeg*)a1);
       
   138 //                break;
       
   139             case EEventAddThread:
       
   140                 HandleAddThread((DThread*)a1);
       
   141                 break;
       
   142             case EEventUpdateThread:    // thread renaming
       
   143                 HandleUpdateThread((DThread*)a1);
       
   144                 break;
       
   145 //            case EEventKillThread:
       
   146             case EEventRemoveThread:
       
   147                 HandleDeleteThread((DThread*)a1);
       
   148                 break;
       
   149 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
       
   150             case EEventAddLibrary:
       
   151                 HandleAddLibrary((DLibrary*)a1, (DThread*)a2);
       
   152                 break;
       
   153             case EEventRemoveLibrary:
       
   154                 HandleDeleteLibrary((DLibrary*)a1);
       
   155                 break;
       
   156 #endif
       
   157             
       
   158             // ignore exception events
       
   159             case EEventSwExc:
       
   160             case EEventHwExc:
       
   161          
       
   162             default:
       
   163                 break;
       
   164             }
       
   165         }
       
   166 //    else if(iTracking && iCount == iPreviousCount)
       
   167 //        {
       
   168 //        // if time stamp is not updated profiling has stopped
       
   169 //        Stop();
       
   170 //        }
       
   171     return DKernelEventHandler::ERunNext;
       
   172     }
       
   173 
       
   174 TInt DMemoryEventHandler::EncodeNameCode()
       
   175     {
       
   176     iSample[0] = 1;
       
   177     iSample[1] = 0xaa;
       
   178     return 2;
       
   179     }
       
   180 
       
   181 // encode mark for new chunk or thread
       
   182 TInt DMemoryEventHandler::EncodeNewCode()
       
   183     {
       
   184     iSample[0] = 1;
       
   185     iSample[1] = 0xda;
       
   186     return 2;
       
   187     }
       
   188 
       
   189 // encode mark for update of chunk or thread
       
   190 TInt DMemoryEventHandler::EncodeUpdateCode()
       
   191     {
       
   192     iSample[0] = 1;
       
   193     iSample[1] = 0xdb;
       
   194     return 2;
       
   195     }
       
   196 
       
   197 // encode mark for removal of chunk or thread
       
   198 TInt DMemoryEventHandler::EncodeRemoveCode()
       
   199     {
       
   200     iSample[0] = 1;
       
   201     iSample[1] = 0xdc;
       
   202     return 2;
       
   203     }
       
   204 
       
   205 // encode the memory sample header in all memory changes
       
   206 TInt DMemoryEventHandler::AddHeader()
       
   207     {
       
   208     TInt err(KErrNone);
       
   209     
       
   210     TUint8 number(4);    // mem sampler id
       
   211 
       
   212     // check if iCount bigger than previous, i.e. at least 1 ms has passed from the previous sample
       
   213     if(iCount > iPreviousCount)
       
   214         {
       
   215         err = this->iSampleBuffer->AddSample(&number,1);
       
   216         err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
       
   217     
       
   218         // add data chunk header
       
   219         TInt length(EncodeUpdateCode());
       
   220         err = iSampleBuffer->AddSample(iSample, length);
       
   221         
       
   222         // add total memory sample in the beginning of each sample
       
   223         length = EncodeTotalMemory();
       
   224         err = iSampleBuffer->AddSample(iSample, length);
       
   225         AddFooter();    // end mark for total memory sample
       
   226         }
       
   227     iPreviousCount = iCount;
       
   228     
       
   229     // add actual sample
       
   230     err = this->iSampleBuffer->AddSample(&number,1);
       
   231     err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4);
       
   232 
       
   233     return err;
       
   234     }
       
   235 
       
   236 // encode the memory sample header in all memory changes
       
   237 TInt DMemoryEventHandler::AddFooter()
       
   238     {
       
   239     TInt err(KErrNone);
       
   240     
       
   241     TUint8 number(0);    // end mark
       
   242     err = this->iSampleBuffer->AddSample(&number,1);
       
   243     
       
   244     return err;
       
   245     }
       
   246 
       
   247 TInt DMemoryEventHandler::EncodeTotalMemory()
       
   248     {   
       
   249     
       
   250     TUint8* size(&iSample[0]);
       
   251     *size = 0;
       
   252 
       
   253     NKern::LockSystem();
       
   254     TInt freeRam(Kern::FreeRamInBytes());
       
   255     TInt totalRam(Kern::SuperPage().iTotalRamSize);
       
   256     NKern::UnlockSystem();
       
   257 
       
   258     iSampleDescriptor.Zero();
       
   259     
       
   260     TUint32 id(0xbabbeaaa);
       
   261     TInt zero(0);
       
   262         
       
   263     iSampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32));
       
   264     *size += sizeof(TUint);
       
   265     
       
   266     iSampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt));
       
   267     *size += sizeof(TInt);
       
   268         
       
   269     // append the cell amount allocated
       
   270     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
       
   271     *size += sizeof(TInt);
       
   272     
       
   273     // append the chunk size
       
   274     iSampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt));
       
   275     *size += sizeof(TInt);
       
   276         
       
   277     // append the thread user stack size
       
   278     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
       
   279     *size += sizeof(TInt);
       
   280 
       
   281     return ((TInt)(*size))+1;
       
   282     }
       
   283 
       
   284 // handle chunk activity
       
   285 TBool DMemoryEventHandler::HandleAddChunk(DChunk* aChunk)
       
   286     {    
       
   287 //    Kern::Printf("New DChunk created: 0x%08x, time: %d", aChunk, iCount);
       
   288     
       
   289     NKern::ThreadEnterCS();
       
   290     Kern::MutexWait(*iLock);
       
   291     // add header first
       
   292     TInt err(AddHeader());
       
   293     
       
   294     if(err != KErrNone)
       
   295         {
       
   296         return EFalse;
       
   297         }
       
   298     
       
   299     // new chunk, add name of it
       
   300     TInt length(EncodeNameCode());
       
   301     iSampleBuffer->AddSample(iSample, length);
       
   302 
       
   303     // new chunk, add name of it
       
   304     length = EncodeChunkName(*aChunk);
       
   305     iSampleBuffer->AddSample(iSample, length);
       
   306     
       
   307     // add new chunk tag
       
   308     length = EncodeNewCode();
       
   309     iSampleBuffer->AddSample(iSample, length);
       
   310 
       
   311     length = EncodeChunkData(*aChunk);
       
   312     iSampleBuffer->AddSample(iSample, length);
       
   313     
       
   314     // add end mark
       
   315     AddFooter();
       
   316     Kern::MutexSignal(*iLock);
       
   317     NKern::ThreadLeaveCS();
       
   318     return ETrue;
       
   319     }
       
   320 
       
   321 TBool DMemoryEventHandler::HandleUpdateChunk(DChunk* aChunk)
       
   322     {
       
   323 //    Kern::Printf("DChunk updated: 0x%08x, time: %d", aChunk, iCount);
       
   324     
       
   325     NKern::ThreadEnterCS();
       
   326     Kern::MutexWait(*iLock);
       
   327     // add header first
       
   328     TInt err(AddHeader());
       
   329     
       
   330     if(err != KErrNone)
       
   331         {
       
   332         return EFalse;
       
   333         }
       
   334     
       
   335     // add new chunk tag
       
   336     TInt length(EncodeUpdateCode());
       
   337     iSampleBuffer->AddSample(iSample, length);
       
   338 
       
   339     length = EncodeChunkData(*aChunk);
       
   340     iSampleBuffer->AddSample(iSample, length);
       
   341 
       
   342     // add end mark
       
   343     AddFooter();
       
   344     Kern::MutexSignal(*iLock);
       
   345     NKern::ThreadLeaveCS();
       
   346     return ETrue;
       
   347     }
       
   348 
       
   349 TBool DMemoryEventHandler::HandleDeleteChunk(DChunk* aChunk)
       
   350     {
       
   351 //    Kern::Printf("DChunk deleted: 0x%08x, time: %d", aChunk, iCount);
       
   352     NKern::ThreadEnterCS();
       
   353     Kern::MutexWait(*iLock);
       
   354     // add header first
       
   355     TInt err(AddHeader());
       
   356     
       
   357     if(err != KErrNone)
       
   358         {
       
   359         return EFalse;
       
   360         }
       
   361     
       
   362     // add new chunk tag
       
   363     TInt length(EncodeRemoveCode());
       
   364     iSampleBuffer->AddSample(iSample, length);
       
   365 
       
   366     length = EncodeChunkData(*aChunk);
       
   367     iSampleBuffer->AddSample(iSample, length);
       
   368 
       
   369     // add end mark
       
   370     AddFooter();
       
   371     Kern::MutexSignal(*iLock);
       
   372     NKern::ThreadLeaveCS();
       
   373     return ETrue;
       
   374     }
       
   375 
       
   376 // handle process activity
       
   377 TBool DMemoryEventHandler::HandleAddProcess(DProcess *aProcess)
       
   378     {
       
   379     return ETrue;
       
   380     }
       
   381 
       
   382 TBool DMemoryEventHandler::HandleUpdateProcess(DProcess *aProcess)
       
   383     {
       
   384     return ETrue;
       
   385     }
       
   386 
       
   387 TBool DMemoryEventHandler::HandleDeleteProcess(DProcess *aProcess)
       
   388     {
       
   389     return ETrue;
       
   390     }
       
   391 
       
   392 // handle thread activity
       
   393 TBool DMemoryEventHandler::HandleAddThread(DThread* aThread)
       
   394     {
       
   395 //    Kern::Printf("DThread added: 0x%08x, time: %d", aThread->iId, iCount);
       
   396     NKern::ThreadEnterCS();
       
   397     Kern::MutexWait(*iLock);
       
   398     // add header first
       
   399     TInt err(AddHeader());
       
   400     
       
   401     if(err != KErrNone)
       
   402         {
       
   403         return EFalse;
       
   404         }
       
   405     
       
   406     // new thread, add name of it
       
   407     TInt length(EncodeNameCode());
       
   408     iSampleBuffer->AddSample(iSample, length);
       
   409     
       
   410     // new chunk, add name of it
       
   411     length = EncodeChunkName(*aThread);
       
   412     iSampleBuffer->AddSample(iSample, length);
       
   413     
       
   414     // add new chunk tag
       
   415     length = EncodeNewCode();
       
   416     iSampleBuffer->AddSample(iSample, length);
       
   417 
       
   418     length = EncodeChunkData(*aThread);
       
   419     iSampleBuffer->AddSample(iSample, length);
       
   420 
       
   421     // add end mark
       
   422     AddFooter();
       
   423     Kern::MutexSignal(*iLock);
       
   424     NKern::ThreadLeaveCS();
       
   425     return ETrue;
       
   426     }
       
   427 
       
   428 TBool DMemoryEventHandler::HandleUpdateThread(DThread* aThread)
       
   429     {
       
   430 //    Kern::Printf("DThread updated: 0x%08x, time: %d", aThread->iId, iCount);
       
   431     NKern::ThreadEnterCS();
       
   432     Kern::MutexWait(*iLock);
       
   433     // add header first
       
   434     TInt err(AddHeader());
       
   435     
       
   436     if(err != KErrNone)
       
   437         {
       
   438         return EFalse;
       
   439         }
       
   440     
       
   441     // add new chunk tag
       
   442     TInt length(EncodeUpdateCode());
       
   443     iSampleBuffer->AddSample(iSample, length);
       
   444 
       
   445     length = EncodeChunkData(*aThread);
       
   446     iSampleBuffer->AddSample(iSample, length);
       
   447 
       
   448     // add end mark
       
   449     AddFooter();
       
   450     Kern::MutexSignal(*iLock);
       
   451     NKern::ThreadLeaveCS();    
       
   452     return ETrue;
       
   453     }
       
   454 
       
   455 TBool DMemoryEventHandler::HandleDeleteThread(DThread* aThread)
       
   456     {
       
   457 //    Kern::Printf("DThread deleted: 0x%08x, time: %d", aThread->iId, iCount);
       
   458     NKern::ThreadEnterCS();
       
   459     Kern::MutexWait(*iLock);
       
   460     // add header first
       
   461     TInt err(AddHeader());
       
   462     
       
   463     if(err != KErrNone)
       
   464         {
       
   465         return EFalse;
       
   466         }
       
   467     
       
   468     // add new chunk tag
       
   469     TInt length(EncodeRemoveCode());
       
   470     iSampleBuffer->AddSample(iSample, length);
       
   471 
       
   472     length = EncodeChunkData(*aThread);
       
   473     iSampleBuffer->AddSample(iSample, length);
       
   474 
       
   475     // add end mark
       
   476     AddFooter();
       
   477     Kern::MutexSignal(*iLock);
       
   478     NKern::ThreadLeaveCS();  
       
   479     return ETrue;
       
   480     }
       
   481 
       
   482 TBool DMemoryEventHandler::HandleAddLibrary(DLibrary* aLibrary, DThread* aThread)
       
   483     {
       
   484     LOGTEXT("DMemoryEventHandler::HandleAddLibrary");
       
   485     Kern::Printf("DLibrary added: 0x%08x, time: %d", aLibrary, iCount);
       
   486     // add header first
       
   487     NKern::ThreadEnterCS();
       
   488     Kern::MutexWait(*iLock);
       
   489     TInt err(AddHeader());
       
   490         
       
   491     if(err != KErrNone)
       
   492         {
       
   493         return EFalse;
       
   494         }
       
   495     
       
   496     // new library, add name of it
       
   497     TInt length(EncodeNameCode());
       
   498     iSampleBuffer->AddSample(iSample, length);
       
   499         
       
   500     // new chunk, add name of it
       
   501     length = EncodeChunkName(*aLibrary);
       
   502     iSampleBuffer->AddSample(iSample, length);
       
   503         
       
   504     // add new chunk tag
       
   505     length = EncodeNewCode();
       
   506     iSampleBuffer->AddSample(iSample, length);
       
   507 
       
   508     length = EncodeChunkData(*aLibrary, *aThread);
       
   509     iSampleBuffer->AddSample(iSample, length);
       
   510 
       
   511     // add end mark
       
   512     AddFooter();
       
   513     Kern::MutexSignal(*iLock);
       
   514     NKern::ThreadLeaveCS();      
       
   515     return ETrue;
       
   516     }
       
   517 
       
   518 TBool DMemoryEventHandler::HandleDeleteLibrary(DLibrary* aLibrary)
       
   519     {
       
   520     Kern::Printf("DLibrary deleted: 0x%08x, time: %d", aLibrary, iCount);
       
   521     NKern::ThreadEnterCS();
       
   522     Kern::MutexWait(*iLock);
       
   523     // add header first
       
   524     TInt err(AddHeader());
       
   525         
       
   526     if(err != KErrNone)
       
   527         {
       
   528         return EFalse;
       
   529         }
       
   530         
       
   531     // add new chunk tag
       
   532     TInt length(EncodeRemoveCode());
       
   533     iSampleBuffer->AddSample(iSample, length);
       
   534     
       
   535     DThread* nullPointer = NULL;
       
   536     length = EncodeChunkData(*aLibrary, *nullPointer);
       
   537     iSampleBuffer->AddSample(iSample, length);
       
   538 
       
   539     // add end mark
       
   540     AddFooter();
       
   541     Kern::MutexSignal(*iLock);
       
   542     NKern::ThreadLeaveCS();        
       
   543     return ETrue;
       
   544     }
       
   545 
       
   546 // encode chunk name 
       
   547 TInt DMemoryEventHandler::EncodeChunkName(DChunk& c)
       
   548     {   
       
   549     // the size of the following name is in the first byte
       
   550     TUint8* size(&iSample[0]);
       
   551     *size = 0;
       
   552         
       
   553     // encode chunk name
       
   554     iSampleDescriptor.Zero();
       
   555     iSampleDescriptor.Append(_L("C_"));
       
   556     c.TraceAppendFullName(iSampleDescriptor,false);
       
   557     *size += iSampleDescriptor.Size();
       
   558         
       
   559     // add chunk object address here
       
   560     TUint32 chunkAddr((TUint32)&c);
       
   561     iSampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
       
   562     *size += sizeof(TUint32);
       
   563 
       
   564     // the size is the descriptor length + the size field
       
   565     LOGSTRING2("Non-Heap Chunk Name - %d",*size);
       
   566     return ((TInt)(*size))+1;           
       
   567     }
       
   568 
       
   569 // encode chunk name 
       
   570 TInt DMemoryEventHandler::EncodeChunkName(DThread& t)
       
   571     {       
       
   572     // the size of the following name is in the first byte
       
   573     TUint8* size(&iSample[0]);
       
   574     *size = 0;
       
   575     iSampleDescriptor.Zero();
       
   576     
       
   577     iSampleDescriptor.Append(_L("T_"));
       
   578     t.TraceAppendFullName(iSampleDescriptor,false);
       
   579     *size += iSampleDescriptor.Size();
       
   580     
       
   581     // copy the 4 bytes from the thread id field
       
   582     iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
       
   583     *size += sizeof(TUint);
       
   584 
       
   585     // the size is the descriptor length + the size field
       
   586     LOGSTRING2("Name - %d",*size);
       
   587     return ((TInt)(*size))+1;
       
   588     }
       
   589 
       
   590 // encode chunk name 
       
   591 TInt DMemoryEventHandler::EncodeChunkName(DLibrary& l)
       
   592     {       
       
   593     LOGTEXT("DMemoryEventHandler::EncodeChunkName (LIBRARY)");
       
   594     // the size of the following name is in the first byte
       
   595     TUint8* size(&iSample[0]);
       
   596     *size = 0;
       
   597     iSampleDescriptor.Zero();
       
   598     
       
   599     iSampleDescriptor.Append(_L("L_"));
       
   600     l.TraceAppendFullName(iSampleDescriptor,false);
       
   601     *size += iSampleDescriptor.Size();
       
   602     
       
   603     // copy the library address here
       
   604     TUint32 libAddr((TUint32)&l);
       
   605     iSampleDescriptor.Append((TUint8*) &libAddr,sizeof(TUint32));
       
   606     *size += sizeof(TUint32);
       
   607 
       
   608     // the size is the descriptor length + the size field
       
   609     LOGSTRING2("Name - %d",*size);
       
   610     return ((TInt)(*size))+1;
       
   611     }
       
   612 
       
   613 // record thread stack changes
       
   614 TInt DMemoryEventHandler::EncodeChunkData(DThread& t)
       
   615     {
       
   616     LOGSTRING("DMemoryEventHandler::EncodeChunkDataT - entry");
       
   617         
       
   618     // the size of the following name is in the first byte
       
   619     TUint8* size(&iSample[0]);
       
   620     *size = 0;
       
   621     iSampleDescriptor.Zero();
       
   622 
       
   623     iSampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
       
   624     *size += sizeof(TUint);
       
   625         
       
   626     // copy the total amount of memory allocated for user side stack
       
   627     iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
       
   628     *size += sizeof(TInt);
       
   629 
       
   630     TInt zero(0);      
       
   631     // append the cell amount allocated (zero, not in use here)
       
   632     iSampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
       
   633     *size += sizeof(TInt);
       
   634     
       
   635     // append the chunk size (this is not a chunk)
       
   636     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint));
       
   637     *size += sizeof(TUint);
       
   638 
       
   639     // append user stack (max) size
       
   640     iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
       
   641     *size += sizeof(TInt);
       
   642 
       
   643 //    Kern::Printf("TData -> %d",*size);
       
   644     return ((TInt)(*size))+1;
       
   645     }
       
   646 
       
   647 // record chunk changes
       
   648 TInt DMemoryEventHandler::EncodeChunkData(DChunk& c)
       
   649     {
       
   650     LOGSTRING("DMemoryEventHandler::EncodeChunkDataC - entry");
       
   651     
       
   652     // the size of the following name is in the first byte
       
   653     TUint8* size(&iSample[0]);
       
   654     *size = 0;
       
   655     iSampleDescriptor.Zero();
       
   656     TInt zero(0);
       
   657 
       
   658     TUint32 address((TUint32)&c);
       
   659         
       
   660     iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
       
   661     *size += sizeof(TUint);
       
   662     
       
   663     // copy the total amount of memory allocated
       
   664     iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
       
   665     *size += sizeof(TInt);
       
   666         
       
   667     // append the cell amount allocated
       
   668     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
       
   669     *size += sizeof(TInt);
       
   670     
       
   671     // append the chunk size
       
   672     iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint));
       
   673     *size += sizeof(TUint);
       
   674         
       
   675     // append the thread user stack size
       
   676     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
       
   677     *size += sizeof(TInt);
       
   678 
       
   679 //    Kern::Printf("CData - %d",*size);
       
   680     return ((TInt)(*size))+1;
       
   681     }
       
   682 
       
   683 // record loaded libraries changes
       
   684 TInt DMemoryEventHandler::EncodeChunkData(DLibrary& l, DThread& t)
       
   685     {    
       
   686     LOGSTRING("DMemoryEventHandler::EncodeChunkDataL - entry");
       
   687     
       
   688     // the size of the following name is in the first byte
       
   689     TUint8* size(&iSample[0]);
       
   690     *size = 0;
       
   691     iSampleDescriptor.Zero();
       
   692     TInt zero(0);
       
   693 
       
   694     TUint32 address((TUint32)&l);
       
   695     
       
   696     iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
       
   697     *size += sizeof(TUint);
       
   698     
       
   699     // append amount of memory that library is allocated
       
   700     iSampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32));
       
   701     *size += sizeof(TInt);
       
   702             
       
   703     // append count of how many times librarys is allocated
       
   704     iSampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt));
       
   705     *size += sizeof(TInt);
       
   706     
       
   707     if(&t != NULL)
       
   708         {
       
   709         // created by thread
       
   710         iSampleDescriptor.Append((TUint8*)&(t),sizeof(TUint32));
       
   711         }
       
   712     else
       
   713         {
       
   714         // removed
       
   715         iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint32));
       
   716         }
       
   717     *size += sizeof(TUint);
       
   718             
       
   719     // append the thread user stack size
       
   720     iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
       
   721     *size += sizeof(TInt);
       
   722     return ((TInt)(*size))+1;
       
   723     }
       
   724