sysanadatacapture/piprofiler/piprofiler_api/inc/ProfilerGenericClassesUsr.inl
changeset 1 3ff3fecb12fe
--- /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 <f32file.h>
+#include <e32svr.h>
+
+#include <piprofiler/EngineUIDs.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(_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
+
+
+