diff -r f0f2b8682603 -r 3ff3fecb12fe sysanadatacapture/piprofiler/piprofiler_api/inc/ProfilerGenericClassesUsr.inl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysanadatacapture/piprofiler/piprofiler_api/inc/ProfilerGenericClassesUsr.inl Thu Feb 11 15:52:57 2010 +0200 @@ -0,0 +1,499 @@ +/* +* 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 + +// 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);iiBuffer = (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(_L("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 + + +