diff -r d27dfa8884ad -r da2cedce4920 piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/piprofiler/plugins/GeneralsPlugin/src/MemSamplerImpl.cpp Tue May 25 14:22:58 2010 +0300 @@ -0,0 +1,976 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include + +#include +#include + +#include "MemSamplerImpl.h" + +// for testing precise stack utilization tracing... +// crashes at the moment + +#include + +#if !defined(__NKERN_H__) +#include +#endif + +#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext)) +#define PROFILER_CHUNK_MARK ((TUint32)0x00001000) +#define PROFILER_MEM_THREAD_MARK ((TUint32)0x00000001) +#define PROFILER_LIBRARY_MARK ((TUint32)0x10000000) +#define PROFILER_MEM_THREAD_UNMARK ~PROFILER_MEM_THREAD_MARK + +#ifdef MEM_EVENT_HANDLER +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS +_LIT8(KMemVersion,"2.03"); +#else +_LIT8(KMemVersion, "2.02"); +#endif +#else +_LIT8(KMemVersion, "1.56"); +#endif + +DMemSamplerImpl::DMemSamplerImpl() : + sampleDescriptor(&(this->sample[1]),0,256) + { + LOGSTRING("MemSamplerImpl::MemSamplerImpl() - konstruktori"); + + iCount = 0; + +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + iSampleType = ESampleThreads; +#else + iSampleThreads = true; +#endif + iTimeToSample = false; + + iTotalMemoryOk = false; + iTotalMemoryNameOk = false; + + iNewChunkCount = 0; + iChunkCount = 0; + iChunksProcessing = ENothingToProcess; + iThreadsProcessing = ENothingToProcess; + + iNewThreadCount = 0; + iThreadCount = 0; + + // reset data structures + for(TInt i(0);iheapChunksToSample[i] = 0; + this->heapChunkNamesToReport[i] = 0; + } + + for(TInt i(0);ithreadsToSample[i] = 0; + this->threadNamesToReport[i] = 0; + } + +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + iLibrariesProcessing = ENothingToProcess; + iNewLibraryCount = 0; + iLibraryCount = 0; + + for(TInt i(0); ilibrariesToSample[i] = 0; + this->libraryNamesToReport[i] = 0; + } +#endif + + } + +DMemSamplerImpl::~DMemSamplerImpl() + { + + } + +TInt DMemSamplerImpl::CreateFirstSample() + { + LOGSTRING("MemSamplerImpl::CreateFirstSample - entry"); + + this->sampleDescriptor.Zero(); + this->sampleDescriptor.Append(_L8("Bappea_V")); + this->sampleDescriptor.Append(KMemVersion); + this->sampleDescriptor.Append(_L8("_MEM")); + + sample[0] = this->sampleDescriptor.Size(); + + LOGSTRING("MemSamplerImpl::CreateFirstSample - exit"); + + return (TInt)(sample[0]+1); + } + +TBool DMemSamplerImpl::SampleNeeded() + { + iCount++; +#ifdef MEM_EVENT_HANDLER + // make the collection of chunks/threads only once, rest will be collected with mem event handler +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv3) == 0)) +#else + if (iCount <= iMemSamplingPeriod && ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0)) +#endif +#else + if ((iCount % iMemSamplingPeriod) == 0 || (iCount % iMemSamplingPeriodDiv2) == 0) +#endif + { + LOGSTRING2("MemSamplerImpl::SampleNeeded - time: %d", iCount); + iTimeToSample = true; + return true; + } + else + { + return false; + } + + } +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS +TInt DMemSamplerImpl::SampleImpl() + { + // Sample threads: + if( iSampleType == ESampleThreads ) + { + if(this->iThreadsProcessing == ENothingToProcess ) + { + if(!iTimeToSample) + { + return 0; + } + else + { + iTimeToSample = false; + // gather first all thread stacks + return GatherThreads(); + } + } + else + { + // process now thread stack list + TInt length = this->ProcessThreads(); + + if(length == 0) + { + this->iThreadsProcessing = ENothingToProcess; + // switch to collect chunk data + iSampleType = ESampleChunks; + } + return length; + } + } + + // Sample chunks: + if( iSampleType == ESampleChunks ) + { + if(this->iChunksProcessing == ENothingToProcess) + { + if(!iTimeToSample) + { + return 0; + } + else + { + iTimeToSample = false; + // gather first all chunks + return GatherChunks(); + } + } + else + { + // still something to go through in lists + TInt length = this->ProcessChunks(); + + if(length == 0) + { + this->iChunksProcessing = ENothingToProcess; + // switch to collect library data + iSampleType = ESampleLibraries; + //iSampleThreads = true; + } + return length; + } + } + + // Sample libraries: + if( iSampleType == ESampleLibraries ) + { + if(this->iLibrariesProcessing == ENothingToProcess ) + { + if(!iTimeToSample) + { + return 0; + } + else + { + iTimeToSample = false; + // gather libraries + return GatherLibraries(); + } + } + else + { + // process now thread stack list + TInt length = this->ProcessLibraries(); + if(length == 0) + { + this->iLibrariesProcessing = ENothingToProcess; + // switch to collect chunk data + iSampleType = ESampleThreads; + } + return length; + } + } + + // should not reach this point... + return 0; + } +#else +TInt DMemSamplerImpl::SampleImpl() + { + // check if either chunk or thread lists have unprocessed items + if(this->iChunksProcessing == ENothingToProcess && !iSampleThreads) + { + if(!iTimeToSample) + { + return 0; + } + else + { + iTimeToSample = false; + // gather first all chunks + return GatherChunks(); + } + } + else if(!iSampleThreads) + { + // still something to go through in lists + TInt length = this->ProcessChunks(); + + if(length == 0) + { + this->iChunksProcessing = ENothingToProcess; + // switch to collect thread data + iSampleThreads = true; + } + return length; + } + + if(this->iThreadsProcessing == ENothingToProcess && iSampleThreads) + { + if(!iTimeToSample) + { + return 0; + } + else + { + iTimeToSample = false; + // gather first all thread stacks + return GatherThreads(); + } + } + + else if(iSampleThreads) + { + // process now thread stack list + TInt length = this->ProcessThreads(); + + if(length == 0) + { + this->iThreadsProcessing = ENothingToProcess; + // switch to collect chunk data + iSampleThreads = false; + } + return length; + } + + // should not reach this point... + return 0; + } +#endif + +inline TInt DMemSamplerImpl::GatherChunks() + { + // encode a process binary + name.Zero(); + + NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex + DObjectCon& chunks = *Kern::Containers()[EChunk]; + chunks.Wait(); // Obtain the container mutex so the list does get changed under us + + this->iChunkCount = 0; + this->iNewChunkCount = 0; + this->iTotalMemoryOk = false; + TInt totalChunkCount(chunks.Count()); + DChunk* c; + + for(TInt i(0);iTraceAppendName(name,false); + const TUint8* ptr = name.Ptr(); + + TAG(c) = (PROFILER_CHUNK_MARK); + this->heapChunkNamesToReport[iNewChunkCount] = c; + iNewChunkCount++; + } + + // the chunk has been tagged, add heap chunks to the list + this->heapChunksToSample[this->iChunkCount] = c; + this->iChunkCount++; + LOGSTRING2("Added chunk %d to Chunks",i); + } + + if(this->iChunkCount > 0 || this->iNewChunkCount > 0) + { + this->iChunksProcessing = EStartingToProcess; + + // process the first sample + TInt length = this->ProcessChunks(); + + if(length == 0) + { + this->iChunksProcessing = ENothingToProcess; + } + + chunks.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return length; + } + + LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); + chunks.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return 0; + } + +inline TInt DMemSamplerImpl::GatherThreads() + { + // The thread memory consumption + + NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex + DObjectCon& threads = *Kern::Containers()[EThread]; + threads.Wait(); // Obtain the container mutex so the list does get changed under us + + this->iThreadCount = 0; + this->iNewThreadCount = 0; + this->iTotalMemoryOk = false; + + TInt totalThreadCount = threads.Count(); + + for(TInt i(0);ithreadNamesToReport[iNewThreadCount] = t; + iNewThreadCount++; + // tag the thread + TAG(t) |= PROFILER_MEM_THREAD_MARK; + } + + // the chunk has been tagged, add heap chunks to the list + this->threadsToSample[this->iThreadCount] = t; + this->iThreadCount++; + LOGSTRING2("Added thread %d to threads to sample",i); + } + + if(this->iThreadCount > 0 || this->iNewThreadCount > 0) + { + this->iThreadsProcessing = EStartingToProcess; + + // process the first sample + TInt length = this->ProcessThreads(); + + if(length == 0) + { + this->iThreadsProcessing = ENothingToProcess; + } + threads.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return length; + } + + LOGTEXT("MemSamplerImpl::SampleImpl - Error, no threads"); + threads.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return 0; + } + +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + +inline TInt DMemSamplerImpl::GatherLibraries() + { + LOGTEXT("MemSamplerImpl::GatherLibraries() - entry"); + // encode a process binary + name.Zero(); + + NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex + DObjectCon& libs = *Kern::Containers()[ELibrary]; + libs.Wait(); // Obtain the container mutex so the list does get changed under us + + this->iLibraryCount = 0; + this->iNewLibraryCount = 0; + this->iTotalMemoryOk = false; + TInt totalLibCount(libs.Count()); + DLibrary* l; + + for(TInt i(0);iTraceAppendName(name,false); + const TUint8* ptr = name.Ptr(); + + TAG(l) = (PROFILER_LIBRARY_MARK); + this->libraryNamesToReport[iNewLibraryCount] = l; + iNewLibraryCount++; + } + + // the library has been tagged, add library to the list + this->librariesToSample[this->iLibraryCount] = l; + this->iLibraryCount++; + LOGSTRING2("Added library %d to Libraries",i); + } + + if(this->iLibraryCount > 0 || this->iNewLibraryCount > 0) + { + this->iLibrariesProcessing = EStartingToProcess; + + // process the first sample + TInt length = this->ProcessLibraries(); + + if(length == 0) + { + this->iLibrariesProcessing = ENothingToProcess; + } + + libs.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return length; + } + + LOGTEXT("MemSamplerImpl::SampleImpl - Error, no libraries"); + libs.Signal(); // Release the container mutex + NKern::ThreadLeaveCS(); // End of critical section + return 0; + } +#endif + +inline TInt DMemSamplerImpl::ProcessChunks() + { + if(iNewChunkCount > 0) + { + if(this->iChunksProcessing == EStartingToProcess) + { + // this is the first sample, encode a code for names + this->iChunksProcessing = EProcessingNames; + return EncodeNameCode(); + } + + if(iTotalMemoryNameOk == false) + { + return EncodeTotalMemoryName(); + } + + // there are new chunk names to report + iNewChunkCount--; + DChunk* c = this->heapChunkNamesToReport[iNewChunkCount]; + return EncodeChunkName(*c); + + } + else if(iChunkCount > 0) + { + if(this->iChunksProcessing == EProcessingNames || this->iChunksProcessing == EStartingToProcess) + { + // this is the first data sample, encode a code for data + this->iChunksProcessing = EProcessingData; + return EncodeDataCode(); + } + + if(this->iTotalMemoryOk == false) + { + return EncodeTotalMemory(); + } + + // there are no new chunks to report + // thus generate the real report + iChunkCount--; + DChunk* c = this->heapChunksToSample[iChunkCount]; + return EncodeChunkData(*c); + } + else + { + // everything is processed + LOGSTRING2(" Chunks processed! Chunk count = %d", iChunkCount); +#ifdef MEM_EVENT_HANDLER + this->iChunksGathered = true; + Kern::Printf("MemSamplerImpl::ProcessChunks() - chunks gathered! Time: %d",iCount); +#endif + return 0; + } + } + +inline TInt DMemSamplerImpl::ProcessThreads() + { + + if(iNewThreadCount > 0) + { + if(this->iThreadsProcessing == EStartingToProcess) + { + // this is the first sample, encode a code for names + this->iThreadsProcessing = EProcessingNames; + return EncodeNameCode(); + } + + if(iTotalMemoryNameOk == false) + { + return EncodeTotalMemoryName(); + } + + iNewThreadCount--; + DThread* t = this->threadNamesToReport[iNewThreadCount]; + return EncodeChunkName(*t); + } + else if(iThreadCount > 0) + { + if(this->iThreadsProcessing == EProcessingNames || this->iThreadsProcessing == EStartingToProcess) + { + // this is the first data sample, encode a code for data + this->iThreadsProcessing = EProcessingData; + return EncodeDataCode(); + } + + if(this->iTotalMemoryOk == false) + { + return EncodeTotalMemory(); + } + + // there are no new threads to report + // thus generate the real report + iThreadCount--; + DThread* t = this->threadsToSample[iThreadCount]; + return EncodeChunkData(*t); + } + else + { + // everything is processed + LOGSTRING2(" Threads processed! Thread count = %d", iThreadCount); +#ifdef MEM_EVENT_HANDLER + this->iThreadsGathered = true; + Kern::Printf("MemSamplerImpl::ProcessThreads() - threads gathered! Time: %d", iCount); +#endif + return 0; + } + } +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS +inline TInt DMemSamplerImpl::ProcessLibraries() + { + LOGTEXT("ProcessLibraries - entry"); + if(iNewLibraryCount > 0) + { + if(this->iLibrariesProcessing == EStartingToProcess) + { + // this is the first sample, encode a code for names + this->iLibrariesProcessing = EProcessingNames; + return EncodeNameCode(); + } + + if(iTotalMemoryNameOk == false) + { + return EncodeTotalMemoryName(); + } + + // there are new library names to report + iNewLibraryCount--; + DLibrary* l = this->libraryNamesToReport[iNewLibraryCount]; + return EncodeChunkName(*l); + + } + else if(iLibraryCount > 0) + { + if(this->iLibrariesProcessing == EProcessingNames || this->iLibrariesProcessing == EStartingToProcess) + { + // this is the first data sample, encode a code for data + this->iLibrariesProcessing = EProcessingData; + return EncodeDataCode(); + } + + if(this->iTotalMemoryOk == false) + { + return EncodeTotalMemory(); + } + + // there are no new libraries to report + // thus generate the real report + iLibraryCount--; + DLibrary* l = this->librariesToSample[iLibraryCount]; + return EncodeChunkData(*l); + } + else + { + // everything is processed + LOGSTRING2(" Libraries processed! Library count = %d", iLibraryCount); + + this->iLibrariesGathered = true; + Kern::Printf("MemSamplerImpl::ProcessLibraries() - libraries gathered! Time: %d",iCount); + + return 0; + } + } +#endif +inline TInt DMemSamplerImpl::EncodeNameCode() + { + sample[0] = 1; + sample[1] = 0xaa; + return 2; + } + +inline TInt DMemSamplerImpl::EncodeDataCode() + { + sample[0] = 1; + sample[1] = 0xdd; + return 2; + } + +inline TInt DMemSamplerImpl::EncodeTotalMemoryName() + { + this->iTotalMemoryNameOk = true; + + TUint8* size = &sample[0]; + *size = 0; + + // encode name + this->sampleDescriptor.Zero(); + this->sampleDescriptor.Append(_L("TOTAL_MEMORY")); + *size += this->sampleDescriptor.Size(); + + // add id here + TUint32 id(0xbabbeaaa); + this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32)); + *size += sizeof(TUint32); + + // the size is the descriptor length + the size field + return ((TInt)(*size))+1; + } + +inline TInt DMemSamplerImpl::EncodeTotalMemory() + { + + TUint8* size = &sample[0]; + *size = 0; + + NKern::LockSystem(); + TInt freeRam = Kern::FreeRamInBytes(); + TInt totalRam = Kern::SuperPage().iTotalRamSize; + NKern::UnlockSystem(); + + this->sampleDescriptor.Zero(); + + TUint32 id(0xbabbeaaa); + TInt zero(0); + + this->sampleDescriptor.Append((TUint8*)&(id),sizeof(TUint32)); + *size += sizeof(TUint); + + this->sampleDescriptor.Append((TUint8*)&(totalRam),sizeof(TInt)); + *size += sizeof(TInt); + + // append the cell amount allocated + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + // append the chunk size + this->sampleDescriptor.Append((TUint8*)&(freeRam),sizeof(TInt)); + *size += sizeof(TInt); + + // append the thread user stack size + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + this->iTotalMemoryOk = true; + + return ((TInt)(*size))+1; + } + +inline TInt DMemSamplerImpl::EncodeChunkName(DChunk& c) + { + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + + // encode chunk name + this->sampleDescriptor.Zero(); + this->sampleDescriptor.Append(_L("C_")); + c.TraceAppendFullName(this->sampleDescriptor,false); + *size += this->sampleDescriptor.Size(); + + // add chunk object address here + TUint32 chunkAddr((TUint32)&c); + this->sampleDescriptor.Append((TUint8*)&(chunkAddr),sizeof(TUint32)); + *size += sizeof(TUint32); + + // the size is the descriptor length + the size field + LOGSTRING2("Non-Heap Chunk Name - %d",*size); + return ((TInt)(*size))+1; + } + +inline TInt DMemSamplerImpl::EncodeChunkName(DThread& t) + { + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + this->sampleDescriptor.Zero(); + + this->sampleDescriptor.Append(_L("T_")); + t.TraceAppendFullName(this->sampleDescriptor,false); + *size += this->sampleDescriptor.Size(); + + // copy the 4 bytes from the thread id field + this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint)); + *size += sizeof(TUint); + + // the size is the descriptor length + the size field + LOGSTRING2("Name - %d",*size); + return ((TInt)(*size))+1; + } +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS +inline TInt DMemSamplerImpl::EncodeChunkName(DLibrary& l) + { + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + + // encode library name + this->sampleDescriptor.Zero(); + this->sampleDescriptor.Append(_L("L_")); + l.TraceAppendFullName(this->sampleDescriptor,false); + *size += this->sampleDescriptor.Size(); + + // add chunk object address here + TUint32 libAddr((TUint32)&l); + this->sampleDescriptor.Append((TUint8*)&(libAddr),sizeof(TUint32)); + *size += sizeof(TUint32); + + // the size is the descriptor length + the size field + LOGSTRING2("Name - %d",*size); + return ((TInt)(*size))+1; + } +#endif +inline TInt DMemSamplerImpl::EncodeChunkData(DChunk& c) + { + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + this->sampleDescriptor.Zero(); + TInt zero(0); + + TUint32 address((TUint32)&c); + + this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32)); + *size += sizeof(TUint); + + // copy the total amount of memory allocated + this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt)); + *size += sizeof(TInt); + + // append the cell amount allocated + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + // append the chunk size + this->sampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TUint)); + *size += sizeof(TUint); + + // append the thread user stack size + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + LOGSTRING2("Data - %d",*size); + return ((TInt)(*size))+1; + + } + +inline TInt DMemSamplerImpl::EncodeChunkData(DThread& t) + { + LOGTEXT("MemSamplerImpl::EncodeChunkData - entry"); + //LOGSTRING2("MemSamplerImpl::EncodeChunkData - processing thread 0x%x ",&t); + + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + this->sampleDescriptor.Zero(); + + LOGTEXT("MemSamplerImpl::EncodeChunkData - cleared"); + + this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint)); + *size += sizeof(TUint); + + // copy the total amount of memory allocated for user side stack + this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt)); + *size += sizeof(TInt); + + TInt zero(0); + // append the cell amount allocated (zero, not in use here) + this->sampleDescriptor.Append((TUint8*)&zero,sizeof(TInt)); + *size += sizeof(TInt); + + // append the chunk size (this is not a chunk) + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TUint)); + *size += sizeof(TUint); + + // append user stack (max) size + this->sampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt)); + *size += sizeof(TInt); + + LOGSTRING2("Data -> %d",*size); + return ((TInt)(*size))+1; + } +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS +inline TInt DMemSamplerImpl::EncodeChunkData(DLibrary& l) + { + LOGTEXT("MemSamplerImpl::EncodeChunkData (Library) - entry"); + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + this->sampleDescriptor.Zero(); + + TUint32 address((TUint32)&l); + + this->sampleDescriptor.Append((TUint8*)&address,sizeof(TUint32)); + *size += sizeof(TUint); + + this->sampleDescriptor.Append((TUint8*)&(l.iCodeSeg->iSize),sizeof(TUint32)); + *size += sizeof(TInt); + + this->sampleDescriptor.Append((TUint8*)&(l.iMapCount),sizeof(TInt)); + *size += sizeof(TInt); + + TInt zero(0); + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + this->sampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); + *size += sizeof(TInt); + + LOGSTRING2("LData - %d",*size); + return ((TInt)(*size))+1; + + } +#endif +void DMemSamplerImpl::Reset() + { + Kern::Printf("MemSamplerImpl::Reset"); + iCount = 0; // sample threads 1 cycle after actual MEM sample time... + this->iTimeToSample = false; + this->iChunkCount = 0; + this->iNewChunkCount = 0; + + this->iTotalMemoryOk = false; + this->iTotalMemoryNameOk = false; + + this->iChunksProcessing = ENothingToProcess; + this->iThreadsProcessing = ENothingToProcess; +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + this->iLibrariesProcessing = ENothingToProcess; + this->iSampleType = ESampleThreads; +#else + this->iSampleThreads = true; +#endif + + this->sampleDescriptor.Zero(); + + // clear all chunk tags + NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex + DObjectCon* chunks = Kern::Containers()[EChunk]; + chunks->Wait(); // Obtain the container mutex so the list does get changed under us + + TInt totalChunkCount = chunks->Count(); + for(TInt i=0;iSignal(); // Release the container mutex + + Kern::Printf("MemSamplerImpl::Reset"); + this->iThreadCount = 0; + this->iNewThreadCount = 0; + this->sampleDescriptor.Zero(); + + // clear all chunk tags + DObjectCon* threads = Kern::Containers()[EThread]; + threads->Wait(); // Obtain the container mutex so the list does get changed under us + + TInt totalThreadCount = threads->Count(); + for(TInt i=0;iSignal(); // Release the container mutex + +#ifdef MEM_EVENT_HANDLER_LIBRARY_EVENTS + this->iLibraryCount = 0; + this->iNewLibraryCount = 0; + this->sampleDescriptor.Zero(); + + // clear all library tags + DObjectCon* libs = Kern::Containers()[ELibrary]; + libs->Wait(); // Obtain the container mutex so the list does get changed under us + + TInt totalLibraryCount = libs->Count(); + for(TInt i=0; iSignal(); // Release the container mutex +#endif + + NKern::ThreadLeaveCS(); // End of critical section + } +