perfsrv/piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
equal deleted inserted replaced
56:aa2539c91954 62:1c2bb2fc7c87
    54     {
    54     {
    55     LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori");
    55     LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori");
    56 
    56 
    57 	iCount = 0;
    57 	iCount = 0;
    58 		
    58 		
    59 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
       
    60 	iSampleType = ESampleThreads;
    59 	iSampleType = ESampleThreads;
    61 #else
    60 	//iSampleType = ESampleChunks;
    62 	iSampleThreads = true;
    61 
    63 #endif
    62 	iTimeToSample = true;
    64 	iTimeToSample = false;
       
    65 	
       
    66 	iTotalMemoryOk = false;
    63 	iTotalMemoryOk = false;
    67 	iTotalMemoryNameOk = false;
    64 	iTotalMemoryNameOk = false;
    68 	
    65 	
    69 	iNewChunkCount = 0;
    66 	iNewChunkCount = 0;
    70 	iChunkCount = 0;
    67 	iChunkCount = 0;
    71 	iChunksProcessing = ENothingToProcess;
    68 	iChunksProcessing = ENothingToProcess;
    72     iThreadsProcessing = ENothingToProcess;
    69     iThreadsProcessing = ENothingToProcess;
    73 	
    70 	
       
    71     iChunksGathered = false;
       
    72     iThreadsGathered = false;
       
    73     
    74 	iNewThreadCount = 0;
    74 	iNewThreadCount = 0;
    75 	iThreadCount = 0;
    75 	iThreadCount = 0;
    76 	
    76 	
    77 	// reset data structures
    77 	// reset data structures
    78     for(TInt i(0);i<KProfilerMaxChunksAmount;i++)
    78     for(TInt i(0);i<KProfilerMaxChunksAmount;i++)
   116 	this->sampleDescriptor.Zero();
   116 	this->sampleDescriptor.Zero();
   117 	this->sampleDescriptor.Append(_L8("Bappea_V"));
   117 	this->sampleDescriptor.Append(_L8("Bappea_V"));
   118 	this->sampleDescriptor.Append(KMemVersion);
   118 	this->sampleDescriptor.Append(KMemVersion);
   119 	this->sampleDescriptor.Append(_L8("_MEM"));
   119 	this->sampleDescriptor.Append(_L8("_MEM"));
   120 	
   120 	
   121 	sample[0] = this->sampleDescriptor.Size();
   121     LOGSTRING2("timestamp : 0x%04x",  iCount);
   122 
   122 
   123 	LOGSTRING("MemSamplerImpl::CreateFirstSample - exit");
   123     LOGSTRING("MemSamplerImpl::CreateFirstSample - exit");
   124 
   124     sample[0] = this->sampleDescriptor.Size();
   125 	return (TInt)(sample[0]+1);
   125     
   126     }
   126     return (TInt)(sample[0]+1);
   127 
   127     }
   128 TBool DMemSamplerImpl::SampleNeeded()
   128 
   129     {
   129 TBool DMemSamplerImpl::SampleNeeded(TUint32 sampleNum)
   130 	iCount++;
   130     {
       
   131     TBool ret(false);
       
   132     iCount = sampleNum;
   131 #ifdef MEM_EVENT_HANDLER
   133 #ifdef MEM_EVENT_HANDLER
   132     // make the collection of chunks/threads only once, rest will be collected with mem event handler
   134     // make the collection of chunks/threads only once, rest will be collected with mem event handler
   133 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   135 
   134 	if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0))
   136 //    #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   135 #else
   137 //    if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0))
   136     if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0))
   138 //    #else
   137 #endif
   139 	if (iCount % iMemSamplingPeriod == 0)
       
   140 //    #endif
       
   141 
   138 #else
   142 #else
   139 	if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)
   143 	if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)
   140 #endif
   144 #endif
   141 	    {
   145 	    {
   142         LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount);
   146         LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount);
   143 		iTimeToSample = true;
   147         ret= true;
   144 		return true;
   148         }
   145         }
   149 	else
   146 	else 
       
   147 	    {
   150 	    {
   148 		return false;
   151 		ret=false;
   149         }
   152         }
   150 
   153 	return ret;
   151     }
   154 	}
   152 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   155 
   153 TInt DMemSamplerImpl::SampleImpl()
   156 /*
   154     {    
   157  * When returns 0, means that all samples done.
   155     // Sample threads:
   158  * Should return length of sample available in iSample
   156     if( iSampleType == ESampleThreads )
   159  */
   157         {    
   160 TInt DMemSamplerImpl::SampleImpl(TUint32 sampleNum)
   158         if(this->iThreadsProcessing == ENothingToProcess )
   161     {
   159             {     
   162     if(iTimeToSample)
   160             if(!iTimeToSample)
   163         {
   161                 {
   164         // Sample threads:
   162                 return 0;
   165         if( iSampleType == ESampleThreads && !iThreadsGathered )
       
   166             {
       
   167             if(this->iThreadsProcessing == ENothingToProcess )
       
   168                 {
       
   169                  // gather first all thread stacks
       
   170                  return GatherThreads(); 
   163                 }
   171                 }
   164             else
   172             else
   165                 {
   173                 {
   166                 iTimeToSample = false;
   174                 // process now thread stack list
   167                 // gather first all thread stacks
   175                 TInt length = this->ProcessThreads();
   168                 return GatherThreads();
   176                 if(length == 0)
   169                 }
   177                     {
   170             }
   178                     this->iThreadsProcessing = ENothingToProcess;
   171         else
   179                     // switch to collect chunk data
   172             {
   180                     iSampleType = ESampleChunks;
   173             // process now thread stack list
   181                     iThreadsGathered = ETrue;
   174             TInt length = this->ProcessThreads();
   182                     }
   175 
   183                 return length;
   176             if(length == 0)
   184                 }
   177                 {
   185             }
   178                 this->iThreadsProcessing = ENothingToProcess;
   186         // Sample chunks:
   179                 // switch to collect chunk data
   187         else if( iSampleType == ESampleChunks && !iChunksGathered)
   180                 iSampleType = ESampleChunks;
   188             {
   181                 }
   189             if(this->iChunksProcessing == ENothingToProcess)
   182             return length;
   190                 {
   183             }
       
   184         }
       
   185 
       
   186     // Sample chunks:
       
   187     if( iSampleType == ESampleChunks )
       
   188         {
       
   189         if(this->iChunksProcessing == ENothingToProcess)
       
   190             {
       
   191             if(!iTimeToSample)
       
   192                 {
       
   193                 return 0;
       
   194                 }
       
   195             else
       
   196                 {
       
   197                 iTimeToSample = false;
       
   198                 // gather first all chunks
   191                 // gather first all chunks
   199                 return GatherChunks();
   192                 return GatherChunks();
   200                 }
   193                 }
   201             }
       
   202         else
       
   203             {
       
   204             // still something to go through in lists
       
   205             TInt length = this->ProcessChunks();
       
   206         
       
   207             if(length == 0) 
       
   208             {
       
   209                 this->iChunksProcessing = ENothingToProcess;
       
   210                 // switch to collect library data
       
   211                 iSampleType = ESampleLibraries;
       
   212                 //iSampleThreads = true;
       
   213             }
       
   214             return length;
       
   215             }
       
   216         }
       
   217         
       
   218     // Sample libraries:
       
   219     if( iSampleType == ESampleLibraries )
       
   220         {
       
   221         if(this->iLibrariesProcessing == ENothingToProcess )
       
   222             {        
       
   223             if(!iTimeToSample)
       
   224                 {             
       
   225                 return 0;
       
   226                 }
       
   227             else
   194             else
   228                 {
   195                 {
   229                 iTimeToSample = false;
   196                 // still something to go through in lists
       
   197                 TInt length = this->ProcessChunks();
       
   198                 if(length == 0) 
       
   199                     {
       
   200                     this->iChunksProcessing = ENothingToProcess;
       
   201                     // switch to collect library data
       
   202                     iSampleType = ESampleLibraries;
       
   203                     iChunksGathered = ETrue;
       
   204                     iThreadsGathered = ETrue;
       
   205                     //iSampleThreads = true;
       
   206                     }
       
   207                 return length;
       
   208                 }
       
   209             }
       
   210 
       
   211     #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
       
   212         // Sample libraries:
       
   213         else if( iSampleType == ESampleLibraries )
       
   214             {
       
   215             if(this->iLibrariesProcessing == ENothingToProcess )
       
   216                 {        
   230                 // gather libraries
   217                 // gather libraries
   231                 return GatherLibraries();
   218                 return GatherLibraries();
   232                 }
   219                 }
   233             }
   220             else
       
   221                 {
       
   222                 // process now thread stack list
       
   223                 TInt length = this->ProcessLibraries();
       
   224                 if(length == 0)
       
   225                     {
       
   226                     this->iLibrariesProcessing = ENothingToProcess;
       
   227                     // switch to collect chunk data
       
   228                     iSampleType = ESampleThreads;
       
   229                     iLibrariesGathered = ETrue;
       
   230                     }
       
   231                 return length;
       
   232                 }
       
   233             }
       
   234     #endif
   234         else
   235         else
   235             {
   236             {
   236             // process now thread stack list
   237             // Will not be executed. Ever. PostSample handles the state change and starting of
   237             TInt length = this->ProcessLibraries();
   238             // memory event handler.
   238             if(length == 0)
   239             iChunksGathered = ETrue;
   239                 {
   240             iThreadsGathered = ETrue;
   240                 this->iLibrariesProcessing = ENothingToProcess;
   241             iTimeToSample = false;
   241                 // switch to collect chunk data
   242             Kern::Printf("MEM sampler - all initial samples generated but we should not be here...!");
   242                 iSampleType = ESampleThreads;
   243             }
   243                 }
   244         }
   244             return length;
   245     else    // not time to sample
   245             }
   246         {
   246         }
   247         LOGSTRING("MEM sampler - not time to sample!");
   247 
   248         }
   248     // should not reach this point...
   249     // should not reach this point...
   249     return 0;
   250     return 0;
   250     }
   251     }
   251 #else
   252 
   252 TInt DMemSamplerImpl::SampleImpl()
       
   253     {
       
   254     // check if either chunk or thread lists have unprocessed items
       
   255     if(this->iChunksProcessing == ENothingToProcess && !iSampleThreads)
       
   256         {
       
   257         if(!iTimeToSample)
       
   258             {
       
   259             return 0;
       
   260             }
       
   261         else
       
   262             {
       
   263             iTimeToSample = false;
       
   264             // gather first all chunks
       
   265             return GatherChunks();
       
   266             }
       
   267         }
       
   268     else if(!iSampleThreads)
       
   269         {
       
   270         // still something to go through in lists
       
   271         TInt length = this->ProcessChunks();
       
   272         
       
   273         if(length == 0) 
       
   274             {
       
   275             this->iChunksProcessing = ENothingToProcess;
       
   276             // switch to collect thread data
       
   277             iSampleThreads = true;
       
   278             }
       
   279         return length;
       
   280         }
       
   281     
       
   282     if(this->iThreadsProcessing == ENothingToProcess && iSampleThreads)
       
   283         {
       
   284         if(!iTimeToSample)
       
   285             {
       
   286             return 0;
       
   287             }
       
   288         else
       
   289             {
       
   290             iTimeToSample = false;
       
   291             // gather first all thread stacks
       
   292             return GatherThreads();
       
   293             }
       
   294         }
       
   295     
       
   296     else if(iSampleThreads)
       
   297         {
       
   298         // process now thread stack list
       
   299         TInt length = this->ProcessThreads();
       
   300 
       
   301         if(length == 0)
       
   302             {
       
   303             this->iThreadsProcessing = ENothingToProcess;
       
   304             // switch to collect chunk data
       
   305             iSampleThreads = false;
       
   306             }
       
   307         return length;
       
   308         }
       
   309 
       
   310     // should not reach this point...
       
   311     return 0;
       
   312     }
       
   313 #endif
       
   314 
   253 
   315 inline TInt DMemSamplerImpl::GatherChunks()
   254 inline TInt DMemSamplerImpl::GatherChunks()
   316     {
   255     {
   317     // encode a process binary
   256     // encode a process binary
   318     name.Zero();
   257     name.Zero();
   319     
       
   320     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   258     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   321     DObjectCon& chunks = *Kern::Containers()[EChunk];
   259     DObjectCon& chunks = *Kern::Containers()[EChunk];
   322     chunks.Wait();  // Obtain the container mutex so the list does get changed under us
   260     chunks.Wait();  // Obtain the container mutex so the list does get changed under us
   323     
   261     
   324     this->iChunkCount = 0; 
   262     this->iChunkCount = 0; 
   325     this->iNewChunkCount = 0;
   263     this->iNewChunkCount = 0;
   326     this->iTotalMemoryOk = false;
   264     this->iTotalMemoryOk = false;
   327     TInt totalChunkCount(chunks.Count());
   265     TInt totalChunkCount(chunks.Count());
   328     DChunk* c; 
   266     DChunk* c; 
   329     
   267     LOGSTRING2("DMemSamplerImpl::GatherChunks() chunk count %d",totalChunkCount);
   330     for(TInt i(0);i<totalChunkCount;i++)
   268     for(TInt i(0);i<totalChunkCount;i++)
   331         {
   269         {
   332         c = (DChunk*)(chunks)[i];
   270         c = (DChunk*)(chunks)[i];
   333 
   271 
   334         LOGSTRING3("Processing chunk %d, tag: 0x%x",i,TAG(c));
   272         //LOGSTRING3("Processing chunk %d, tag: 0x%x",i,TAG(c));
   335         
   273         
   336         if( (TAG(c) & 0x0000ffff) != PROFILER_CHUNK_MARK)
   274         if( (TAG(c) & 0x0000ffff) != PROFILER_CHUNK_MARK)
   337             {
   275             {
   338             LOGSTRING4("Marking chunk %d/%d, old tag 0x%x",i,(totalChunkCount-1), TAG(c));
   276             //LOGSTRING4("Marking chunk %d/%d, old tag 0x%x",i,(totalChunkCount-1), TAG(c));
   339             // this chunk has not been tagged yet
   277             // this chunk has not been tagged yet
   340             name.Zero();
   278             name.Zero();
   341             c->TraceAppendName(name,false);
   279             c->TraceAppendName(name,false);
   342             
   280             
   343             TAG(c) = (PROFILER_CHUNK_MARK);
   281             TAG(c) = (PROFILER_CHUNK_MARK);
   346             }
   284             }
   347 
   285 
   348         // the chunk has been tagged, add heap chunks to the list
   286         // the chunk has been tagged, add heap chunks to the list
   349         this->heapChunksToSample[this->iChunkCount] = c;
   287         this->heapChunksToSample[this->iChunkCount] = c;
   350         this->iChunkCount++;
   288         this->iChunkCount++;
   351         LOGSTRING2("Added chunk %d to Chunks",i);
   289         }
   352         }
   290         LOGSTRING2("Added  %d Chunks", totalChunkCount);
   353 
   291 
   354     if(this->iChunkCount > 0 || this->iNewChunkCount > 0)
   292     if(this->iChunkCount > 0 || this->iNewChunkCount > 0)
   355         {
   293         {
   356         this->iChunksProcessing = EStartingToProcess;
   294         this->iChunksProcessing = EStartingToProcess;
   357         
   295         
   358         // process the first sample
   296         // process the first sample
   359         TInt length = this->ProcessChunks();
   297         TInt length = this->ProcessChunks();
   360         
       
   361         if(length == 0)
   298         if(length == 0)
   362             {
   299             {
   363             this->iChunksProcessing = ENothingToProcess;
   300             this->iChunksProcessing = ENothingToProcess;
   364             }
   301             }
   365     
   302     
   375     }
   312     }
   376 
   313 
   377 inline TInt DMemSamplerImpl::GatherThreads()
   314 inline TInt DMemSamplerImpl::GatherThreads()
   378     {
   315     {
   379     // The thread memory consumption
   316     // The thread memory consumption
   380     
       
   381     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   317     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   382     DObjectCon& threads = *Kern::Containers()[EThread];
   318     DObjectCon& threads = *Kern::Containers()[EThread];
   383     threads.Wait(); // Obtain the container mutex so the list does get changed under us
   319     threads.Wait(); // Obtain the container mutex so the list does get changed under us
   384     
   320     
   385     this->iThreadCount = 0; 
   321     this->iThreadCount = 0; 
   386     this->iNewThreadCount = 0;
   322     this->iNewThreadCount = 0;
   387     this->iTotalMemoryOk = false;           
   323     this->iTotalMemoryOk = false;           
   388 
   324 
   389     TInt totalThreadCount = threads.Count();
   325     TInt totalThreadCount = threads.Count();
   390 
   326     LOGSTRING2("DMemSamplerImpl::GatherThreads() thread count %d",totalThreadCount);
   391     for(TInt i(0);i<totalThreadCount;i++)
   327     for(TInt i(0);i<totalThreadCount;i++)
   392         {
   328         {
   393         DThread* t = (DThread*)(threads)[i];
   329         DThread* t = (DThread*)(threads)[i];
   394 
   330 
   395         LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
   331         //LOGSTRING3("Processing thread %d, tag: 0x%x",i,TAG(t));
   396 
   332 
   397         if( (TAG(t) & PROFILER_MEM_THREAD_MARK) == 0)
   333         if( (TAG(t) & PROFILER_MEM_THREAD_MARK) == 0)
   398             {
   334             {
   399             LOGSTRING4("Marking thread %d/%d, old tag 0x%x",i,(totalThreadCount-1), TAG(t));
   335             //LOGSTRING4("Marking thread %d/%d, old tag 0x%x",i,(totalThreadCount-1), TAG(t));
   400             // this thread's chunk has not been reported yet
   336             // this thread's chunk has not been reported yet
   401             this->threadNamesToReport[iNewThreadCount] = t;
   337             this->threadNamesToReport[iNewThreadCount] = t;
   402             iNewThreadCount++;
   338             iNewThreadCount++;
   403             // tag the thread
   339             // tag the thread
   404             TAG(t) |= PROFILER_MEM_THREAD_MARK;
   340             TAG(t) |= PROFILER_MEM_THREAD_MARK;
   405             }
   341             }
   406 
   342 
   407         // the chunk has been tagged, add heap chunks to the list
   343         // the chunk has been tagged, add heap chunks to the list
   408         this->threadsToSample[this->iThreadCount] = t;
   344         this->threadsToSample[this->iThreadCount] = t;
   409         this->iThreadCount++;
   345         this->iThreadCount++;
   410         LOGSTRING2("Added thread %d to threads to sample",i);
   346         //LOGSTRING2("Added thread %d to threads to sample",i);
   411         }
   347         }
   412     
   348 
       
   349     LOGSTRING3("Added %d threads. ithreadcount %d",totalThreadCount, iThreadCount);
       
   350    
   413     if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
   351     if(this->iThreadCount > 0 || this->iNewThreadCount > 0)
   414         {
   352         {
   415         this->iThreadsProcessing = EStartingToProcess;
   353         this->iThreadsProcessing = EStartingToProcess;
   416         
   354       // process the first sample
   417         // process the first sample
       
   418         TInt length = this->ProcessThreads();
   355         TInt length = this->ProcessThreads();
   419         
       
   420         if(length == 0)
   356         if(length == 0)
   421             {
   357             {
   422             this->iThreadsProcessing = ENothingToProcess;
   358             this->iThreadsProcessing = ENothingToProcess;
   423             }
   359             }
   424         threads.Signal();  // Release the container mutex
   360         threads.Signal();  // Release the container mutex
   425         NKern::ThreadLeaveCS();  // End of critical section
   361         NKern::ThreadLeaveCS();  // End of critical section
   426         return length;
   362         return length;
   427         }
   363         }
   428     
   364     
   429     LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); 
   365     LOGTEXT("DMemSamplerImpl::GatherThreads() - Error, no threads"); 
   430     threads.Signal();  // Release the container mutex
   366     threads.Signal();  // Release the container mutex
   431     NKern::ThreadLeaveCS();  // End of critical section
   367     NKern::ThreadLeaveCS();  // End of critical section
   432     return 0;
   368     return 0;
   433     }
   369     }
   434 
   370 
   498     }
   434     }
   499 #endif
   435 #endif
   500 
   436 
   501 inline TInt DMemSamplerImpl::ProcessChunks()
   437 inline TInt DMemSamplerImpl::ProcessChunks()
   502     {
   438     {
   503     if(iNewChunkCount > 0)
   439     if(iHandledChunks < 50)
   504         {
   440         {
   505         if(this->iChunksProcessing == EStartingToProcess)
   441         if(iNewChunkCount > 0)
   506             {
   442             {
   507             // this is the first sample, encode a code for names
   443             if(this->iChunksProcessing == EStartingToProcess)
   508             this->iChunksProcessing = EProcessingNames;
   444                 {
   509             return EncodeNameCode();
   445                 // this is the first sample, encode a code for names
   510             }
   446                 this->iChunksProcessing = EProcessingNames;
   511 
   447                 iHandledChunks++;
   512         if(iTotalMemoryNameOk == false)
   448                 return EncodeNameCode();
   513             {
   449                 }
   514             return EncodeTotalMemoryName();
   450     
   515             }
   451             if(iTotalMemoryNameOk == false)
   516         
   452                 {
   517         // there are new chunk names to report
   453                 iHandledChunks++;
   518         iNewChunkCount--;
   454                 return EncodeTotalMemoryName();
   519         DChunk* c = this->heapChunkNamesToReport[iNewChunkCount];
   455                 }
   520         return EncodeChunkName(*c);
   456             iNewChunkCount--;
   521         
   457             DChunk* c = this->heapChunkNamesToReport[iNewChunkCount];
   522         }
   458             iHandledChunks++;
   523     else if(iChunkCount > 0)
   459             return EncodeChunkName(*c);
   524         {
   460             }
   525         if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess)
   461         else if(iChunkCount > 0)
   526             {
   462             {
   527             // this is the first data sample, encode a code for data
   463             if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess)
   528             this->iChunksProcessing = EProcessingData;
   464                 {
   529             return EncodeDataCode();
   465                 // this is the first data sample, encode a code for data
   530             }
   466                 this->iChunksProcessing = EProcessingData;
   531         
   467                 iHandledChunks++;
   532         if(this->iTotalMemoryOk == false)
   468                 return EncodeDataCode();
   533             {
   469                 }
   534             return EncodeTotalMemory();	
   470             
   535             }
   471             if(this->iTotalMemoryOk == false)
   536 
   472                 {
   537         // there are no new chunks to report
   473                 iHandledChunks++;
   538         // thus generate the real report
   474                 return EncodeTotalMemory();
   539         iChunkCount--;
   475                 }
   540         DChunk* c = this->heapChunksToSample[iChunkCount];
   476     
   541         return EncodeChunkData(*c);
   477             // there are no new chunks to report
       
   478             // thus generate the real report
       
   479             iChunkCount--;
       
   480             DChunk* c = this->heapChunksToSample[iChunkCount];
       
   481             iHandledChunks++;
       
   482             return EncodeChunkData(*c);
       
   483             }
       
   484         else
       
   485             {
       
   486             // everything is processed
       
   487             LOGSTRING2("MemSamplerImpl::ProcessChunks() Chunks processed! Chunk count = %d", iChunkCount);
       
   488     #ifdef MEM_EVENT_HANDLER
       
   489             this->iChunksGathered = ETrue;
       
   490             LOGSTRING2("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount);
       
   491     #endif
       
   492             return 0;
       
   493             }
   542         }
   494         }
   543     else
   495     else
   544         {
   496         {
   545         // everything is processed
   497         LOGSTRING("MemSamplerImpl::ProcessChunks() 0");
   546         LOGSTRING2(" Chunks processed! Chunk count = %d", iChunkCount);
   498         iHandledChunks =0;
       
   499         }
       
   500     return -1;
       
   501     }
       
   502 
       
   503 inline TInt DMemSamplerImpl::ProcessThreads()
       
   504     {
       
   505     if(iHandledThreads < 50)
       
   506         {
       
   507         if(iNewThreadCount > 0)
       
   508             {
       
   509             if(this->iThreadsProcessing == EStartingToProcess)
       
   510                 {
       
   511                 // this is the first sample, encode a code for names
       
   512                 this->iThreadsProcessing = EProcessingNames;
       
   513                 iHandledThreads++;
       
   514                 return EncodeNameCode();
       
   515                 }
       
   516             
       
   517             if(iTotalMemoryNameOk == false)
       
   518                 {
       
   519                 LOGSTRING("MemSamplerImpl::ProcessThreads() Encoding total memory name!");
       
   520                 iHandledThreads++;
       
   521                 return EncodeTotalMemoryName();
       
   522                 }
       
   523             iNewThreadCount--;
       
   524             DThread* t = this->threadNamesToReport[iNewThreadCount];
       
   525             iHandledThreads++;
       
   526             return EncodeChunkName(*t);
       
   527             }
       
   528         else if(iThreadCount > 0)
       
   529             {
       
   530             if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess)
       
   531                 {
       
   532                 // this is the first data sample, encode a code for data
       
   533                 this->iThreadsProcessing = EProcessingData;
       
   534                 iHandledThreads++;
       
   535                 return EncodeDataCode();
       
   536                 }
       
   537     
       
   538             if(this->iTotalMemoryOk == false)
       
   539                 {
       
   540                 iHandledThreads++;
       
   541                 return EncodeTotalMemory(); 
       
   542                 }
       
   543     
       
   544             // there are no new threads to report
       
   545             // thus generate the real report
       
   546             iThreadCount--;
       
   547             DThread* t = this->threadsToSample[iThreadCount];
       
   548             iHandledThreads++;
       
   549             return EncodeChunkData(*t);
       
   550             }
       
   551         else
       
   552             {   
       
   553             // everything is processed
       
   554             LOGSTRING2("MemSamplerImpl::ProcessThreads() Threads processed! Thread count = %d", iThreadCount);
   547 #ifdef MEM_EVENT_HANDLER
   555 #ifdef MEM_EVENT_HANDLER
   548         this->iChunksGathered = true;
   556             this->iThreadsGathered = true;
   549         Kern::Printf("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount);
   557             LOGSTRING2("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount);
   550 #endif
   558 #endif
   551         return 0;
   559             return 0;
   552         }
   560             }
   553     }
       
   554 
       
   555 inline TInt DMemSamplerImpl::ProcessThreads()
       
   556     {
       
   557 
       
   558     if(iNewThreadCount > 0)
       
   559         {
       
   560         if(this->iThreadsProcessing == EStartingToProcess)
       
   561             {
       
   562             // this is the first sample, encode a code for names
       
   563             this->iThreadsProcessing = EProcessingNames;
       
   564             return EncodeNameCode();
       
   565             }
       
   566         
       
   567         if(iTotalMemoryNameOk == false)
       
   568             {
       
   569             return EncodeTotalMemoryName();
       
   570             }
       
   571 
       
   572         iNewThreadCount--;
       
   573         DThread* t = this->threadNamesToReport[iNewThreadCount];
       
   574         return EncodeChunkName(*t);
       
   575         }
       
   576     else if(iThreadCount > 0)
       
   577         {
       
   578         if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess)
       
   579             {
       
   580             // this is the first data sample, encode a code for data
       
   581             this->iThreadsProcessing = EProcessingData;
       
   582             return EncodeDataCode();
       
   583             }
       
   584 
       
   585         if(this->iTotalMemoryOk == false)
       
   586             {
       
   587             return EncodeTotalMemory(); 
       
   588             }
       
   589 
       
   590         // there are no new threads to report
       
   591         // thus generate the real report
       
   592         iThreadCount--;
       
   593         DThread* t = this->threadsToSample[iThreadCount];
       
   594         return EncodeChunkData(*t);
       
   595         }
   561         }
   596     else
   562     else
   597         {   
   563         {
   598         // everything is processed
   564         LOGSTRING("MemSamplerImpl::ProcessThreads() 0");
   599         LOGSTRING2(" Threads processed! Thread count = %d", iThreadCount);
   565         iHandledThreads=0;
   600 #ifdef MEM_EVENT_HANDLER
   566         }
   601         this->iThreadsGathered = true;
   567     return -1;
   602         Kern::Printf("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount);
   568     }
   603 #endif
   569 
   604         return 0;
       
   605         }
       
   606     }
       
   607 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   570 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   608 inline TInt DMemSamplerImpl::ProcessLibraries()
   571 inline TInt DMemSamplerImpl::ProcessLibraries()
   609     {
   572     {
   610     LOGTEXT("ProcessLibraries - entry");
   573     LOGTEXT("ProcessLibraries - entry");
   611     if(iNewLibraryCount > 0)
   574     
       
   575     if(iHandledLibs < 50)
       
   576         {
       
   577         if(iNewLibraryCount > 0)
   612         {
   578         {
   613         if(this->iLibrariesProcessing == EStartingToProcess)
   579         if(this->iLibrariesProcessing == EStartingToProcess)
   614             {
   580             {
   615             // this is the first sample, encode a code for names
   581             // this is the first sample, encode a code for names
   616             this->iLibrariesProcessing = EProcessingNames;
   582             this->iLibrariesProcessing = EProcessingNames;
       
   583             iHandledLibs++;
   617             return EncodeNameCode();
   584             return EncodeNameCode();
   618             }
   585             }
   619 
   586 
   620         if(iTotalMemoryNameOk == false)
   587         if(iTotalMemoryNameOk == false)
   621             {
   588             {
       
   589             iHandledLibs++;
   622             return EncodeTotalMemoryName();
   590             return EncodeTotalMemoryName();
   623             }
   591             }
   624         
   592         
   625         // there are new library names to report
   593         // there are new library names to report
   626         iNewLibraryCount--;
   594         iNewLibraryCount--;
   627         DLibrary* l = this->libraryNamesToReport[iNewLibraryCount];
   595         DLibrary* l = this->libraryNamesToReport[iNewLibraryCount];
       
   596         iHandledLibs++;
   628         return EncodeChunkName(*l);
   597         return EncodeChunkName(*l);
   629         
   598         
   630         }
   599         }
   631     else if(iLibraryCount > 0)
   600     else if(iLibraryCount > 0)
   632         {
   601         {
   633         if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess)
   602         if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess)
   634             {
   603             {
   635             // this is the first data sample, encode a code for data
   604             // this is the first data sample, encode a code for data
   636             this->iLibrariesProcessing = EProcessingData;
   605             this->iLibrariesProcessing = EProcessingData;
       
   606             iHandledLibs++;
   637             return EncodeDataCode();
   607             return EncodeDataCode();
   638             }
   608             }
   639         
   609         
   640         if(this->iTotalMemoryOk == false)
   610         if(this->iTotalMemoryOk == false)
   641             {
   611             {
       
   612             iHandledLibs++;
   642             return EncodeTotalMemory(); 
   613             return EncodeTotalMemory(); 
   643             }
   614             }
   644 
   615 
   645         // there are no new libraries to report
   616         // there are no new libraries to report
   646         // thus generate the real report
   617         // thus generate the real report
   647         iLibraryCount--;
   618         iLibraryCount--;
   648         DLibrary* l = this->librariesToSample[iLibraryCount];
   619         DLibrary* l = this->librariesToSample[iLibraryCount];
       
   620         iHandledLibs++;
   649         return EncodeChunkData(*l);
   621         return EncodeChunkData(*l);
   650         }
   622         }
   651     else
   623     else
   652         {
   624         {
   653         // everything is processed
   625         // everything is processed
   654         LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount);
   626         LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount);
   655 
   627 
   656         this->iLibrariesGathered = true;
   628         this->iLibrariesGathered = true;
   657         Kern::Printf("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount);
   629         LOGSTRING2("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount);
   658 
   630 
   659         return 0;
   631         return 0;
   660         }
   632         }
   661     }
   633     }
   662 #endif
   634     else
       
   635         {
       
   636         LOGSTRING("MemSamplerImpl::ProcessLibs() 0");
       
   637         iHandledLibs =0;
       
   638         }
       
   639     return -1;
       
   640     }
       
   641 #endif
       
   642 
   663 inline TInt DMemSamplerImpl::EncodeNameCode()
   643 inline TInt DMemSamplerImpl::EncodeNameCode()
   664     {
   644     {
   665 	sample[0] = 1;
   645 	sample[0] = 1;
   666 	sample[1] = 0xaa;
   646 	sample[1] = 0xaa;
   667 	return 2;
   647 	return 2;
   695 	return ((TInt)(*size))+1;	
   675 	return ((TInt)(*size))+1;	
   696     }
   676     }
   697 
   677 
   698 inline TInt DMemSamplerImpl::EncodeTotalMemory()
   678 inline TInt DMemSamplerImpl::EncodeTotalMemory()
   699     {	
   679     {	
   700 	
       
   701 	TUint8* size = &sample[0];
   680 	TUint8* size = &sample[0];
   702 	*size = 0;
   681 	*size = 0;
   703 
   682 
   704 	NKern::LockSystem();
   683 	NKern::LockSystem();
   705 	TInt freeRam = Kern::FreeRamInBytes();
   684 	TInt freeRam = Kern::FreeRamInBytes();
   751 	this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
   730 	this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32));
   752 	*size += sizeof(TUint32);
   731 	*size += sizeof(TUint32);
   753 
   732 
   754 	// the size is the descriptor length + the size field
   733 	// the size is the descriptor length + the size field
   755 	LOGSTRING2("Non-Heap Chunk Name - %d",*size);
   734 	LOGSTRING2("Non-Heap Chunk Name - %d",*size);
   756 	return ((TInt)(*size))+1;			
   735 	return ((TInt)(*size))+1;
   757     }
   736     }
   758 
   737 
   759 inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t)
   738 inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t)
   760     {		
   739     {		
   761 	// the size of the following name is in the first byte
   740 	// the size of the following name is in the first byte
   801 inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c)
   780 inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c)
   802     {
   781     {
   803 	// the size of the following name is in the first byte
   782 	// the size of the following name is in the first byte
   804 	TUint8* size = &sample[0];
   783 	TUint8* size = &sample[0];
   805 	*size = 0;
   784 	*size = 0;
       
   785 	
       
   786     TInt zero(0);
   806 	this->sampleDescriptor.Zero();
   787 	this->sampleDescriptor.Zero();
   807 	TInt zero(0);
       
   808 
       
   809 	TUint32 address((TUint32)&c);
   788 	TUint32 address((TUint32)&c);
   810 		
   789 		
   811 	this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
   790 	this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32));
   812 	*size += sizeof(TUint);
   791 	*size += sizeof(TUint32);
   813 	
   792 	LOGSTRING2("address - 0x%04x",&address);
   814 	// copy the total amount of memory allocated
   793 	// copy the total amount of memory allocated
   815 	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
   794 	this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt));
   816 	*size += sizeof(TInt);
   795 	*size += sizeof(TInt);
   817 		
   796 		
   818 	// append the cell amount allocated
   797 	// append the cell amount allocated
   825 		
   804 		
   826 	// append the thread user stack size
   805 	// append the thread user stack size
   827 	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
   806 	this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt));
   828 	*size += sizeof(TInt);
   807 	*size += sizeof(TInt);
   829 
   808 
   830 	LOGSTRING2("Data - %d",*size);
   809 	LOGSTRING2("chunk Data - %d",*size);
   831 	return ((TInt)(*size))+1;
   810 	return ((TInt)(*size))+1;
   832 
       
   833     }
   811     }
   834 
   812 
   835 inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t)
   813 inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t)
   836     {
   814     {
   837 	LOGTEXT("MemSamplerImpl::EncodeChunkData - entry");
       
   838 	//LOGSTRING2("MemSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t);
       
   839 		
       
   840 	// the size of the following name is in the first byte
   815 	// the size of the following name is in the first byte
   841 	TUint8* size = &sample[0];
   816 	TUint8* size = &sample[0];
   842 	*size = 0;
   817 	*size = 0;
       
   818     TInt zero(0);
   843 	this->sampleDescriptor.Zero();
   819 	this->sampleDescriptor.Zero();
   844 
   820 	//LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared");
   845 	LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared");
       
   846 
   821 
   847 	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
   822 	this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint));
   848 	*size += sizeof(TUint);
   823 	*size += sizeof(TUint);
   849 		
   824 		
   850 	// copy the total amount of memory allocated for user side stack
   825 	// copy the total amount of memory allocated for user side stack
   851 	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
   826 	this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt));
   852 	*size += sizeof(TInt);
   827 	*size += sizeof(TInt);
   853 
   828 
   854 	TInt zero(0);		
   829 
   855 	// append the cell amount allocated (zero, not in use here)
   830 	// append the cell amount allocated (zero, not in use here)
   856 	this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
   831 	this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt));
   857 	*size += sizeof(TInt);
   832 	*size += sizeof(TInt);
   858 	
   833 	
   859 	// append the chunk size (this is not a chunk)
   834 	// append the chunk size (this is not a chunk)
   899 
   874 
   900     }
   875     }
   901 #endif
   876 #endif
   902 void DMemSamplerImpl::Reset()
   877 void DMemSamplerImpl::Reset()
   903     {
   878     {
   904 	Kern::Printf("MemSamplerImpl::Reset");
   879     LOGSTRING("MemSamplerImpl::Reset - entry");
   905 	iCount = 0; // sample threads 1 cycle after actual MEM sample time...
   880 	iCount = 0; // sample threads 1 cycle after actual MEM sample time...
   906     this->iTimeToSample = false;
   881     this->iTimeToSample = true;
   907     this->iChunkCount = 0;
   882     this->iChunkCount = 0;
   908 	this->iNewChunkCount = 0;
   883 	this->iNewChunkCount = 0;
   909 	
   884 	
   910 	this->iTotalMemoryOk = false;
   885 	this->iTotalMemoryOk = false;
   911 	this->iTotalMemoryNameOk = false;
   886 	this->iTotalMemoryNameOk = false;
   912 
   887 
   913 	this->iChunksProcessing = ENothingToProcess;
   888 	this->iChunksProcessing = ENothingToProcess;
   914     this->iThreadsProcessing = ENothingToProcess;
   889     this->iThreadsProcessing = ENothingToProcess;
   915 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   890 #ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS
   916     this->iLibrariesProcessing = ENothingToProcess;
   891     this->iLibrariesProcessing = ENothingToProcess;
       
   892 #else
   917     this->iSampleType = ESampleThreads;
   893     this->iSampleType = ESampleThreads;
   918 #else
   894     //this->iSampleType = ESampleChunks;
   919     this->iSampleThreads = true;
   895     //this->iSampleThreads = true;
   920 #endif
   896 #endif
   921     
   897     this->sampleDescriptor.Zero();
   922 	this->sampleDescriptor.Zero();
   898     // clear all chunk tags
   923 	
       
   924 	// clear all chunk tags
       
   925     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   899     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   926 	DObjectCon* chunks = Kern::Containers()[EChunk];
   900 	DObjectCon* chunks = Kern::Containers()[EChunk];
   927     chunks->Wait(); // Obtain the container mutex so the list does get changed under us
   901     chunks->Wait(); // Obtain the container mutex so the list does get changed under us
   928 
   902 
   929 	TInt totalChunkCount = chunks->Count();
   903 	TInt totalChunkCount = chunks->Count();
   932 		DChunk* c = (DChunk*)(*chunks)[i];
   906 		DChunk* c = (DChunk*)(*chunks)[i];
   933 		TAG(c) = 0;
   907 		TAG(c) = 0;
   934 	    }
   908 	    }
   935 	chunks->Signal();  // Release the container mutex
   909 	chunks->Signal();  // Release the container mutex
   936 
   910 
   937 	Kern::Printf("MemSamplerImpl::Reset");
   911 	LOGSTRING("MemSamplerImpl::Reset");
   938 	this->iThreadCount = 0;
   912 	this->iThreadCount = 0;
   939 	this->iNewThreadCount = 0;
   913 	this->iNewThreadCount = 0;
   940 	this->sampleDescriptor.Zero();
   914 	this->sampleDescriptor.Zero();
   941 
   915 
   942 	// clear all chunk tags
   916 	// clear all thread tags
   943 	DObjectCon* threads = Kern::Containers()[EThread];
   917 	DObjectCon* threads = Kern::Containers()[EThread];
   944     threads->Wait(); // Obtain the container mutex so the list does get changed under us
   918     threads->Wait(); // Obtain the container mutex so the list does get changed under us
   945 
   919 
   946 	TInt totalThreadCount = threads->Count();
   920 	TInt totalThreadCount = threads->Count();
   947 	for(TInt i=0;i<totalThreadCount;i++)
   921 	for(TInt i=0;i<totalThreadCount;i++)
   970 #endif
   944 #endif
   971 
   945 
   972     NKern::ThreadLeaveCS();  // End of critical section
   946     NKern::ThreadLeaveCS();  // End of critical section
   973     }
   947     }
   974 
   948 
       
   949 
       
   950 // end of file