--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.inl Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,498 @@
+/*
+* 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 <f32file.h>
+#include <e32svr.h>
+
+#include <piprofiler/ProfilerTraces.h>
+
+// constants
+const TInt KInitialFreeBufferAmount = 4;
+
+/*
+ *
+ * Class CProfilerBufferHandler implementation
+ *
+ */
+inline CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::NewL - entry"));
+ CProfilerBufferHandler* self = new(ELeave) CProfilerBufferHandler(aStream, aSampler);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+inline CProfilerBufferHandler::CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
+ : CActive(EPriorityStandard),
+ iSampler(aSampler),
+ iObserver(aStream)
+ {
+ }
+
+inline CProfilerBufferHandler::~CProfilerBufferHandler()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::~CProfilerBufferHandler() - entry"));
+ }
+
+inline void CProfilerBufferHandler::ConstructL()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::ConstructL - entry"));
+ iBufferInProcess = 0;
+ iEndOfStreamDetected = false;
+
+ iFinished = 0;
+ // add the buffer handler to the active scheduler
+ CActiveScheduler::Add(this);
+ }
+
+inline void CProfilerBufferHandler::StartReceivingData()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - entry"));
+
+ iEndOfStreamDetected = false;
+ // this method initiates receiving data from the sampler
+ iBufferInProcess = iObserver.GetNextFreeBuffer();
+
+ LOGSTRING5("CProfilerBufferHandler::StartReceivingData - 0x%x -> b:0x%x s:%d d:%d",
+ iBufferInProcess,
+ iBufferInProcess->iBuffer,
+ iBufferInProcess->iBufferSize,
+ iBufferInProcess->iDataSize);
+
+ iSampler.FillThisStreamBuffer(iBufferInProcess,iStatus);
+
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - SetActive"));
+ SetActive();
+
+ LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - exit"));
+ }
+
+inline TInt CProfilerBufferHandler::RunError(TInt aError)
+ {
+ // handle the error case by stopping the trace
+ HandleEndOfStream();
+ return aError;
+ }
+
+inline void CProfilerBufferHandler::HandleEndOfStream()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunError - entry"));
+ // Cancel has been called, the stream should be about to end now,
+ // we will wait for the rest of the buffers to be filled synchronously
+ // the end of the stream will be indicated through an empty buffer
+ // at first, complete the ongoing request
+ if(iStatus == KRequestPending && iBufferInProcess != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1"));
+
+ // wait for the buffer to be filled synchronously
+ User::WaitForRequest(iStatus);
+
+ // add the received buffer to the list of filled buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ // continue writing to output
+ iObserver.NotifyWriter();
+
+ if(iBufferInProcess->iDataSize == 0)
+ {
+ // a buffer with size 0 was received
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1.1"));
+ iEndOfStreamDetected = true;
+ }
+
+ // there will be no more asynchronous requests
+ iBufferInProcess = 0;
+ }
+ else if (iBufferInProcess != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2"));
+
+ // add the buffer into filled, i.e. ready-to-write buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ if(iBufferInProcess->iDataSize == 0)
+ {
+ // a buffer with size 0 was received
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2.1"));
+ iEndOfStreamDetected = true;
+ }
+ // there will be no more asynchronous requests
+ iBufferInProcess = 0;
+ }
+
+ // then, continue until end of stream has been reached
+ while(iEndOfStreamDetected == false)
+ {
+ // the end of stream has not yet been detected, so get more
+ // buffers from the sampler, until we get an empty one
+
+ if(iStatus == KRequestPending)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - ERROR 1"));
+ }
+
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3"));
+
+ TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
+ iSampler.FillThisStreamBuffer(nextFree,iStatus);
+ // wait for the buffer to be filled synchronously
+ User::WaitForRequest(iStatus);
+
+ // call the writer plugin to write data to output
+ iObserver.AddToFilledBuffers(nextFree);
+ iObserver.NotifyWriter();
+
+ // check if end-of-data message (i.e. data size is 0 sized) received
+ if(nextFree->iDataSize == 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3.1"));
+ // a buffer with size 0 was received
+ iEndOfStreamDetected = true;
+ nextFree = 0;
+ }
+ }
+ }
+
+inline void CProfilerBufferHandler::RunL()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - entry"));
+
+ // is called by the active scheduler
+ // when a buffer has been received
+
+ // buffer with dataSize 0 is returned when the sampling ends
+ if(iBufferInProcess->iDataSize != 0)
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - buffer received"));
+
+ TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
+
+ LOGSTRING5("CProfilerBufferHandler::RunL - 0x%x -> b:0x%x s:%d d:%d",
+ nextFree,
+ nextFree->iBuffer,
+ nextFree->iBufferSize,
+ nextFree->iDataSize);
+
+ iSampler.FillThisStreamBuffer(nextFree,iStatus);
+
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - issued new sample command"));
+
+ // add the received buffer to the list of filled buffers
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ // the empty buffer is now the one being processed
+ iBufferInProcess = nextFree;
+
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - SetActive"));
+ SetActive();
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - end of stream detected"));
+ iEndOfStreamDetected = true;
+
+ // add the empty buffer to the writer so that it will also get the information
+ // about the finished stream
+ iObserver.AddToFilledBuffers(iBufferInProcess);
+ iObserver.NotifyWriter();
+
+ iBufferInProcess = 0;
+ Cancel();
+
+ }
+ LOGTEXT(_L("CProfilerBufferHandler::RunL - exit"));
+ }
+
+inline void CProfilerBufferHandler::DoCancel()
+ {
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - entry"));
+ HandleEndOfStream();
+ LOGTEXT(_L("CProfilerBufferHandler::DoCancel - exit"));
+ }
+
+
+/*
+ *
+ * Class CProfilerSampleStream implementation
+ *
+ * - used by Plugin
+ **/
+
+inline CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::NewL - entry"));
+ CProfilerSampleStream* self = new(ELeave) CProfilerSampleStream(aBufSize);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+inline CProfilerSampleStream::CProfilerSampleStream(TInt aBufSize) :
+ iBufferSize(aBufSize)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - entry"));
+
+ iFilledBuffers = 0;
+ iFreeBuffers = 0;
+ iFinished = 0;
+
+ LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - exit"));
+ }
+
+inline CProfilerSampleStream::~CProfilerSampleStream()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - entry"));
+
+ // empty all buffers
+ EmptyBuffers();
+
+ LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - exit"));
+ }
+
+inline void CProfilerSampleStream::ConstructL()
+ {
+
+ }
+
+inline void CProfilerSampleStream::SetWriter(CWriterPluginInterface& aWriter)
+ {
+ // set writer plugin
+ iWriter = &aWriter;
+ }
+
+inline void CProfilerSampleStream::Finalise()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::Finalise - entry"));
+ }
+
+inline void CProfilerSampleStream::ResetBuffers()
+ {
+
+ // empty buffers
+ EmptyBuffers();
+
+ // re-initialise buffers
+ InitialiseBuffers();
+ }
+
+inline void CProfilerSampleStream::InitialiseBuffers()
+ {
+ // re-initialize member variables
+ iFilledBuffers = 0;
+ iFreeBuffers = 0;
+ iFinished = 0;
+
+ // create three(orig. two) new TBapBuf objects and add them to the
+ // list of free buffers
+ for(TInt i(0);i<KInitialFreeBufferAmount;i++)
+ {
+ // alloc new buffer
+ TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+ newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+
+ // initialize the new buffer
+ newBuf->iBufferSize = iBufferSize;
+ newBuf->iDataSize = 0;
+ newBuf->iNext = 0;
+ newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+ newBuf->iDes->SetLength(sizeof(TBapBuf));
+ newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+ newBuf->iBufDes->SetLength(iBufferSize);
+ AddToFreeBuffers(newBuf);
+ }
+ }
+
+inline void CProfilerSampleStream::EmptyBuffers()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - entry"));
+
+ // delete all free buffers
+ while(iFreeBuffers != 0)
+ {
+ LOGSTRING2("CProfilerSampleStream::EmptyBuffers - deleting 0x%x",iFreeBuffers);
+
+ // store the next buffer in the list
+ TBapBuf* nextFree = iFreeBuffers->iNext;
+ // delete the first one in the list
+ delete iFreeBuffers->iBufDes;
+ delete iFreeBuffers->iDes;
+ delete iFreeBuffers->iBuffer;
+ delete iFreeBuffers;
+ // set the list start to the next buffer
+ iFreeBuffers = nextFree;
+ }
+ iFreeBuffers = 0;
+ LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - exit"));
+ }
+
+inline TBapBuf* CProfilerSampleStream::GetNextFreeBuffer()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - entry"));
+
+ // get a new buffer from the free buffers list
+ TBapBuf* nextFree = iFreeBuffers;
+
+ // check if we got a buffer or not
+ if(nextFree == 0)
+ {
+ // if there are no free buffers,
+ // create a new one
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - creating new buffer"));
+ TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
+ if(newBuf != 0)
+ {
+ newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
+ if(newBuf->iBuffer != 0)
+ {
+ newBuf->iBufferSize = iBufferSize;
+ newBuf->iDataSize = 0;
+ newBuf->iNext = 0;
+ newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
+ newBuf->iDes->SetLength(sizeof(TBapBuf));
+ newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
+ newBuf->iBufDes->SetLength(iBufferSize);
+ nextFree = newBuf;
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (1)!!"));
+ return 0;
+ }
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (2)!!"));
+ delete newBuf;
+ return 0;
+ }
+ }
+ else
+ {
+ // set the list to point to next free buffer
+ iFreeBuffers = nextFree->iNext;
+ }
+
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - exit"));
+ return nextFree;
+ }
+
+inline void CProfilerSampleStream::AddToFilledBuffers(TBapBuf* aFilledBuffer)
+ {
+ LOGSTRING2("CProfilerSampleStream::AddToFilledBuffers - entry, size %d", aFilledBuffer->iDataSize);
+
+ // add this buffer to the list of filled buffers
+ if(iFilledBuffers == 0)
+ {
+ // the list is empty, so add the the beginning of the list
+ // there is no next buffer in the list at the moment
+ aFilledBuffer->iNext = 0;
+ iFilledBuffers = aFilledBuffer;
+ }
+ else
+ {
+ // there are buffers in the list, add this buffer to the beginning of the list
+ aFilledBuffer->iNext = iFilledBuffers;
+ iFilledBuffers = aFilledBuffer;
+ }
+ LOGTEXT(_L("CProfilerSampleStream::AddToFilledBuffers - exit"));
+ }
+
+TBapBuf* CProfilerSampleStream::GetNextFilledBuffer()
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - entry"));
+
+ if(iFilledBuffers == 0)
+ {
+ // there are no filled buffers in the list
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - no filled bufs"));
+ return 0;
+ }
+ else
+ {
+ // get a buffer from the end of the list
+ TBapBuf* buf = iFilledBuffers;
+ TBapBuf* prev = 0;
+
+ if(buf->iNext == 0)
+ {
+ // this was the last (and only) buffer
+ iFilledBuffers = 0;
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - last filled"));
+ return buf;
+ }
+ else
+ {
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - searching last filled"));
+ while(buf->iNext != 0)
+ {
+ // there are two or more buffers in the list
+ // proceed until the end of the list is found
+ prev = buf;
+ buf = buf->iNext;
+ }
+ // now buf->next is 0, return buf and set the next
+ // element of prev to NULL
+ prev->iNext = 0;
+ LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - found last"));
+ return buf;
+ }
+ }
+ }
+
+inline void CProfilerSampleStream::AddToFreeBuffers(TBapBuf* aFreeBuffer)
+ {
+ LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - entry"));
+
+ // set data size of the buffer to 0
+ aFreeBuffer->iDataSize = 0;
+
+ // add this buffer to the list of free buffers
+ if(iFreeBuffers == 0)
+ {
+ // this is the first buffer, so set the next to point to NULL
+ aFreeBuffer->iNext = 0;
+ }
+ else
+ {
+ // otherwise set to point to the beginning of the list
+ aFreeBuffer->iNext = iFreeBuffers;
+ }
+
+ // set this buffer to be the first one in the list
+ iFreeBuffers = aFreeBuffer;
+
+ LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - exit"));
+ }
+
+void CProfilerSampleStream::NotifyWriter()
+ {
+ // notify writer plugin to write data from filled buffer list
+ LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - entry"));
+ iWriter->WriteData();
+ LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - exit"));
+ }
+
+// end of file
+
+
+