diff -r f0f2b8682603 -r 3ff3fecb12fe sysanadatacapture/piprofiler/piprofiler/plugins/GeneralsPlugin/src/PriSamplerImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysanadatacapture/piprofiler/piprofiler/plugins/GeneralsPlugin/src/PriSamplerImpl.cpp Thu Feb 11 15:52:57 2010 +0200 @@ -0,0 +1,312 @@ +/* +* 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 "PriSamplerImpl.h" + +#if !defined(__NKERN_H__) +#include +#endif + +#define TAG(obj) (*(TUint32*)&(obj->iAsyncDeleteNext)) +#define PROFILER_THREAD_MARK ((TUint32)0x00000002) + + +PriSamplerImpl::PriSamplerImpl() : + sampleDescriptor(&(this->sample[1]),0,256) + { + LOGTEXT("PriSamplerImpl::PriSamplerImpl() - konstruktori"); + + iCountti = 50; // sample threads 16 cycles before actual MEM and PRI sample time... + iNewThreadCount = 0; + iThreadCount = 0; + iProcessing = ENothingToProcess; + + for(TInt i=0;ithreadsToSample[i] = 0; + this->threadNamesToReport[i] = 0; + } + + } + +PriSamplerImpl::~PriSamplerImpl() + { + + } + +TInt PriSamplerImpl::CreateFirstSample() + { + LOGTEXT("PriSamplerImpl::CreateFirstSample - entry"); + + this->sampleDescriptor.Zero(); + this->sampleDescriptor.Append(_L8("Bappea_V")); + this->sampleDescriptor.Append(PROFILER_PRI_SAMPLER_VERSION); + this->sampleDescriptor.Append(_L8("_PRI")); + + sample[0] = this->sampleDescriptor.Size(); + + LOGTEXT("PriSamplerImpl::CreateFirstSample - exit"); + + return (TInt)(sample[0]+1); + } + +TBool PriSamplerImpl::SampleNeeded() + { + iCountti++; + if(iCountti % (iPriSamplingPeriod) == 0) + { + LOGTEXT("PriSamplerImpl::SampleNeeded - true"); + return true; + } + else + { + return false; + } + } + + +TInt PriSamplerImpl::SampleImpl() + { + /* + * + * EKA-2 implementation of PRI trace + * + */ + if(this->iProcessing == ENothingToProcess) + { + if((iCountti % iPriSamplingPeriod) != 0 ) return 0; + + LOGTEXT("Processing threads..."); + + DObjectCon& threads = *Kern::Containers()[EThread]; + + // PRI trace variables + this->iThreadCount = 0; + this->iNewThreadCount = 0; + TInt totalThreadCount = threads.Count(); + + for(TInt i=0;ithreadNamesToReport[iNewThreadCount] = t; + iNewThreadCount++; + // tag the thread + TAG(t) |= PROFILER_THREAD_MARK; + LOGSTRING2("New Thread %d",i); + } + else + { + LOGSTRING3("Thread %d marked already - 0x%x",i,TAG(t)); + } + + // the thread 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->iProcessing = EStartingToProcess; + + // process the first sample + TInt length = this->ProcessChunks(); + + if(length == 0) + { + this->iProcessing = ENothingToProcess; + } + + return length; + } + else + { + // there were no threads, should not take place + LOGTEXT("PriSamplerImpl::SampleImpl - Error, no threads"); + return 0; + } + } + else + { + TInt length = this->ProcessChunks(); + if(length == 0) + { + this->iProcessing = ENothingToProcess; + } + return length; + } + } + +inline TInt PriSamplerImpl::ProcessChunks() + { + /* + * + * EKA-2 implementation of PRI trace + * + */ + + if(iNewThreadCount > 0) + { + if(this->iProcessing == EStartingToProcess) + { + // this is the first sample, encode a code for names + this->iProcessing = EProcessingNames; + return EncodeNameCode(); + } + + // there are new thread names to report + iNewThreadCount--; + DThread* t = this->threadNamesToReport[iNewThreadCount]; + return EncodeChunkName(*t); + } + else if(iThreadCount > 0) + { + if(this->iProcessing == EProcessingNames || this->iProcessing == EStartingToProcess) + { + // this is the first data sample, encode a code for data + this->iProcessing = EProcessingData; + return EncodeDataCode(); + } + + // there are no new chunks to report + // thus generate the real report + iThreadCount--; + DThread* t = this->threadsToSample[iThreadCount]; + LOGSTRING2("PriSamplerImpl::ProcessChunks - starting to process thread 0x%x",t); + return EncodeChunkData(*t); + } + else + { + // everything is processed + return 0; + } + } + +inline TInt PriSamplerImpl::EncodeNameCode() + { + sample[0] = 1; + sample[1] = 0xbb; // pri trace name code + return 2; + } + +inline TInt PriSamplerImpl::EncodeDataCode() + { + sample[0] = 1; + sample[1] = 0xee; // pri trace data code + return 2; + } + + +inline TInt PriSamplerImpl::EncodeChunkName(DThread& t) + { + // the size of the following name is in the first byte + TUint8* size = &sample[0]; + *size = 0; + this->sampleDescriptor.Zero(); + + 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 size - %d",*size); + return ((TInt)(*size))+1; + } + + +inline TInt PriSamplerImpl::EncodeChunkData(DThread& t) + { + LOGTEXT("PriSamplerImpl::EncodeChunkData - entry"); + LOGSTRING2("PriSamplerImpl::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("PriSamplerImpl::EncodeChunkData - cleared"); + + // append the thread id + this->sampleDescriptor.Append((TUint8*)&(t.iId),sizeof(TUint)); + *size += sizeof(TUint); + +// NKern::LockSystem(); +// TInt priority(-1); +// if(&t && t.Open()== KErrNone) +// { +// priority = t.iDefaultPriority; +// } +// NKern::UnlockSystem(); + + // append the priority of the nanokernel fast semaphore +// this->sampleDescriptor.Append((TUint8*)&priority,sizeof(TUint8)); + // append the priority of the nanokernel fast semaphore + this->sampleDescriptor.Append((TUint8*)&(t.iNThread.iPriority),sizeof(TUint8)); + // add space because EKA-1 implementation needs it + this->sampleDescriptor.Append((TUint8)0x0); + *size += 2*sizeof(TUint8); + + LOGTEXT("PriSamplerImpl::EncodeChunkData - appended priority"); + + + LOGSTRING2("Data size - %d",*size); + return ((TInt)(*size))+1; + } + + +void PriSamplerImpl::Reset() + { + /* + * + * EKA-2 implementation of PRI trace + * + */ + + LOGTEXT("PriSamplerImpl::Reset"); + iCountti = 50; // sample threads 16 cycles before actual MEM and PRI sample time... + this->iThreadCount = 0; + this->iNewThreadCount = 0; + this->iProcessing = ENothingToProcess; + this->sampleDescriptor.Zero(); + + + // clear all thread tags + DObjectCon* threads = Kern::Containers()[EThread]; + TInt totalThreadCount = threads->Count(); + for(TInt i=0;i