piprofiler/piprofiler_plat/inc/ProfilerGenericClassesUsr.inl
changeset 22 a009639409f5
equal deleted inserted replaced
17:67c6ff54ec25 22:a009639409f5
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <f32file.h>
       
    20 #include <e32svr.h>
       
    21 
       
    22 #include <piprofiler/ProfilerTraces.h>
       
    23 
       
    24 // constants
       
    25 const TInt KInitialFreeBufferAmount = 4;
       
    26 
       
    27 /*
       
    28  *
       
    29  *	Class CProfilerBufferHandler implementation
       
    30  *
       
    31  */
       
    32 inline CProfilerBufferHandler* CProfilerBufferHandler::NewL(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
       
    33 	{
       
    34 	LOGTEXT(_L("CProfilerBufferHandler::NewL - entry"));
       
    35 	CProfilerBufferHandler* self = new(ELeave) CProfilerBufferHandler(aStream, aSampler);
       
    36     CleanupStack::PushL(self);
       
    37     self->ConstructL();
       
    38     CleanupStack::Pop(self);
       
    39     return self;   
       
    40 	}
       
    41 
       
    42 inline CProfilerBufferHandler::CProfilerBufferHandler(CProfilerSampleStream& aStream, RPluginSampler& aSampler)
       
    43     : CActive(EPriorityStandard),
       
    44     iSampler(aSampler),
       
    45     iObserver(aStream)
       
    46     {
       
    47     }
       
    48 
       
    49 inline CProfilerBufferHandler::~CProfilerBufferHandler()
       
    50 	{
       
    51 	LOGTEXT(_L("CProfilerBufferHandler::~CProfilerBufferHandler() - entry"));
       
    52 	}
       
    53 
       
    54 inline void CProfilerBufferHandler::ConstructL()
       
    55 	{
       
    56 	LOGTEXT(_L("CProfilerBufferHandler::ConstructL - entry"));
       
    57 	iBufferInProcess = 0;
       
    58 	iEndOfStreamDetected = false;
       
    59 
       
    60 	iFinished = 0;
       
    61 	// add the buffer handler to the active scheduler
       
    62 	CActiveScheduler::Add(this);
       
    63 	}
       
    64 
       
    65 inline void CProfilerBufferHandler::StartReceivingData()
       
    66 	{
       
    67 	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - entry"));
       
    68 
       
    69 	iEndOfStreamDetected = false;
       
    70 	// this method initiates receiving data from the sampler
       
    71 	iBufferInProcess = iObserver.GetNextFreeBuffer();
       
    72 
       
    73 	LOGSTRING5("CProfilerBufferHandler::StartReceivingData - 0x%x -> b:0x%x s:%d d:%d",
       
    74 					iBufferInProcess,
       
    75 					iBufferInProcess->iBuffer,
       
    76 					iBufferInProcess->iBufferSize,
       
    77 					iBufferInProcess->iDataSize);
       
    78 
       
    79 	iSampler.FillThisStreamBuffer(iBufferInProcess,iStatus);
       
    80 
       
    81 	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - SetActive"));
       
    82 	SetActive();
       
    83 
       
    84 	LOGTEXT(_L("CProfilerBufferHandler::StartReceivingData - exit"));
       
    85 	}
       
    86 
       
    87 inline TInt CProfilerBufferHandler::RunError(TInt aError)
       
    88     {
       
    89     // handle the error case by stopping the trace
       
    90     HandleEndOfStream();
       
    91     return aError;
       
    92     }
       
    93 
       
    94 inline void CProfilerBufferHandler::HandleEndOfStream()
       
    95     {
       
    96     LOGTEXT(_L("CProfilerBufferHandler::RunError - entry"));
       
    97     // Cancel has been called, the stream should be about to end now,
       
    98     // we will wait for the rest of the buffers to be filled synchronously
       
    99     // the end of the stream will be indicated through an empty buffer
       
   100     // at first, complete the ongoing request
       
   101     if(iStatus == KRequestPending && iBufferInProcess != 0)
       
   102         {
       
   103         LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1"));
       
   104 
       
   105         // wait for the buffer to be filled synchronously
       
   106         User::WaitForRequest(iStatus);
       
   107         
       
   108         // add the received buffer to the list of filled buffers
       
   109         iObserver.AddToFilledBuffers(iBufferInProcess);
       
   110         // continue writing to output
       
   111         iObserver.NotifyWriter();
       
   112         
       
   113         if(iBufferInProcess->iDataSize == 0)
       
   114             {
       
   115             // a buffer with size 0 was received
       
   116             LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 1.1"));
       
   117             iEndOfStreamDetected = true;
       
   118             }
       
   119 
       
   120         // there will be no more asynchronous requests
       
   121         iBufferInProcess = 0;
       
   122         }
       
   123     else if (iBufferInProcess != 0)
       
   124         {
       
   125         LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2"));
       
   126 
       
   127         // add the buffer into filled, i.e. ready-to-write buffers
       
   128         iObserver.AddToFilledBuffers(iBufferInProcess);
       
   129         iObserver.NotifyWriter();
       
   130         
       
   131         if(iBufferInProcess->iDataSize == 0)
       
   132             {
       
   133             // a buffer with size 0 was received
       
   134             LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 2.1"));
       
   135             iEndOfStreamDetected = true;
       
   136             }       
       
   137         // there will be no more asynchronous requests
       
   138         iBufferInProcess = 0;   
       
   139         }
       
   140 
       
   141     // then, continue until end of stream has been reached
       
   142     while(iEndOfStreamDetected == false)
       
   143         {
       
   144         // the end of stream has not yet been detected, so get more
       
   145         // buffers from the sampler, until we get an empty one
       
   146 
       
   147         if(iStatus == KRequestPending)
       
   148             {
       
   149             LOGTEXT(_L("CProfilerBufferHandler::DoCancel - ERROR 1"));
       
   150             }
       
   151 
       
   152         LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3"));
       
   153 
       
   154         TBapBuf* nextFree = iObserver.GetNextFreeBuffer();  
       
   155         iSampler.FillThisStreamBuffer(nextFree,iStatus);
       
   156         // wait for the buffer to be filled synchronously
       
   157         User::WaitForRequest(iStatus);
       
   158         
       
   159         // call the writer plugin to write data to output
       
   160         iObserver.AddToFilledBuffers(nextFree);
       
   161         iObserver.NotifyWriter();
       
   162         
       
   163         // check if end-of-data message (i.e. data size is 0 sized) received
       
   164         if(nextFree->iDataSize == 0)
       
   165             {
       
   166             LOGTEXT(_L("CProfilerBufferHandler::DoCancel - case 3.1"));
       
   167             // a buffer with size 0 was received
       
   168             iEndOfStreamDetected = true;
       
   169             nextFree = 0;
       
   170             }
       
   171         }   
       
   172     }
       
   173 
       
   174 inline void CProfilerBufferHandler::RunL()
       
   175 	{
       
   176 	LOGTEXT(_L("CProfilerBufferHandler::RunL - entry"));
       
   177 
       
   178 	// is called by the active scheduler
       
   179 	// when a buffer has been received
       
   180 
       
   181 	// buffer with dataSize 0 is returned when the sampling ends
       
   182 	if(iBufferInProcess->iDataSize != 0)
       
   183 	    {
       
   184 	    LOGTEXT(_L("CProfilerBufferHandler::RunL - buffer received"));
       
   185 
       
   186 		TBapBuf* nextFree = iObserver.GetNextFreeBuffer();
       
   187 		
       
   188 		LOGSTRING5("CProfilerBufferHandler::RunL - 0x%x -> b:0x%x s:%d d:%d",
       
   189 					nextFree,
       
   190 					nextFree->iBuffer,
       
   191 					nextFree->iBufferSize,
       
   192 					nextFree->iDataSize);
       
   193 
       
   194 		iSampler.FillThisStreamBuffer(nextFree,iStatus);
       
   195 
       
   196 		LOGTEXT(_L("CProfilerBufferHandler::RunL - issued new sample command"));
       
   197 
       
   198 		// add the received buffer to the list of filled buffers
       
   199 		iObserver.AddToFilledBuffers(iBufferInProcess);
       
   200 		iObserver.NotifyWriter();
       
   201 
       
   202         // the empty buffer is now the one being processed
       
   203         iBufferInProcess = nextFree;
       
   204         
       
   205         LOGTEXT(_L("CProfilerBufferHandler::RunL - SetActive"));
       
   206         SetActive();        
       
   207 		}
       
   208 	else
       
   209 		{
       
   210 		LOGTEXT(_L("CProfilerBufferHandler::RunL - end of stream detected"));
       
   211 		iEndOfStreamDetected = true;
       
   212 		
       
   213 		// add the empty buffer to the writer so that it will also get the information
       
   214 		// about the finished stream
       
   215 		iObserver.AddToFilledBuffers(iBufferInProcess);
       
   216 		iObserver.NotifyWriter();
       
   217 
       
   218 		iBufferInProcess = 0;
       
   219 		Cancel();
       
   220 
       
   221 		}
       
   222 	LOGTEXT(_L("CProfilerBufferHandler::RunL - exit"));
       
   223 	}
       
   224 
       
   225 inline void CProfilerBufferHandler::DoCancel()
       
   226     {
       
   227     LOGTEXT(_L("CProfilerBufferHandler::DoCancel - entry"));
       
   228     HandleEndOfStream();
       
   229     LOGTEXT(_L("CProfilerBufferHandler::DoCancel - exit"));
       
   230     }
       
   231 
       
   232 
       
   233 /*
       
   234  *
       
   235  *	Class CProfilerSampleStream implementation
       
   236  *
       
   237  *  - used by Plugin
       
   238  **/
       
   239 
       
   240 inline CProfilerSampleStream* CProfilerSampleStream::NewL(TInt aBufSize)
       
   241 	{
       
   242 	LOGTEXT(_L("CProfilerSampleStream::NewL - entry"));
       
   243 	CProfilerSampleStream* self = new(ELeave) CProfilerSampleStream(aBufSize);
       
   244     CleanupStack::PushL(self);
       
   245     self->ConstructL();
       
   246     CleanupStack::Pop(self);
       
   247     return self;   
       
   248 	}
       
   249 
       
   250 inline CProfilerSampleStream::CProfilerSampleStream(TInt aBufSize) : 
       
   251     iBufferSize(aBufSize)
       
   252 	{
       
   253 	LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - entry"));
       
   254 	
       
   255 	iFilledBuffers = 0;
       
   256     iFreeBuffers = 0;
       
   257     iFinished = 0;
       
   258     
       
   259 	LOGTEXT(_L("CProfilerSampleStream::CProfilerSampleStream - exit"));	
       
   260 	}
       
   261 
       
   262 inline CProfilerSampleStream::~CProfilerSampleStream()
       
   263 	{
       
   264 	LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - entry"));
       
   265 
       
   266 	// empty all buffers
       
   267 	EmptyBuffers();
       
   268 	    
       
   269 	LOGTEXT(_L("CProfilerSampleStream::~CProfilerSampleStream - exit"));
       
   270 	}
       
   271 
       
   272 inline void CProfilerSampleStream::ConstructL()
       
   273 	{
       
   274 
       
   275 	}
       
   276 
       
   277 inline void CProfilerSampleStream::SetWriter(CWriterPluginInterface& aWriter)
       
   278     {
       
   279     // set writer plugin
       
   280     iWriter = &aWriter;
       
   281     }
       
   282 
       
   283 inline void CProfilerSampleStream::Finalise()
       
   284 	{
       
   285 	LOGTEXT(_L("CProfilerSampleStream::Finalise - entry"));
       
   286 	}
       
   287 
       
   288 inline void CProfilerSampleStream::ResetBuffers()
       
   289     {
       
   290 
       
   291     // empty buffers
       
   292     EmptyBuffers();
       
   293 
       
   294     // re-initialise buffers
       
   295     InitialiseBuffers();
       
   296     }
       
   297 
       
   298 inline void CProfilerSampleStream::InitialiseBuffers()
       
   299     {
       
   300     // re-initialize member variables
       
   301     iFilledBuffers = 0;
       
   302     iFreeBuffers = 0;
       
   303     iFinished = 0;
       
   304     
       
   305     // create three(orig. two) new TBapBuf objects and add them to the
       
   306     // list of free buffers
       
   307     for(TInt i(0);i<KInitialFreeBufferAmount;i++)
       
   308         {
       
   309         // alloc new buffer
       
   310         TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
       
   311         newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
       
   312 
       
   313         // initialize the new buffer
       
   314         newBuf->iBufferSize = iBufferSize;
       
   315         newBuf->iDataSize = 0;
       
   316         newBuf->iNext = 0;
       
   317         newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
       
   318         newBuf->iDes->SetLength(sizeof(TBapBuf));
       
   319         newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
       
   320         newBuf->iBufDes->SetLength(iBufferSize);
       
   321         AddToFreeBuffers(newBuf);
       
   322         }
       
   323     }
       
   324 
       
   325 inline void CProfilerSampleStream::EmptyBuffers()
       
   326     {
       
   327 	LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - entry"));
       
   328 
       
   329 	// delete all free buffers
       
   330 	while(iFreeBuffers != 0)
       
   331 	    {
       
   332 		LOGSTRING2("CProfilerSampleStream::EmptyBuffers - deleting 0x%x",iFreeBuffers);
       
   333 
       
   334 		// store the next buffer in the list
       
   335 		TBapBuf* nextFree = iFreeBuffers->iNext;
       
   336 		// delete the first one in the list
       
   337 		delete iFreeBuffers->iBufDes;
       
   338 		delete iFreeBuffers->iDes;
       
   339 		delete iFreeBuffers->iBuffer;
       
   340 		delete iFreeBuffers;
       
   341 		// set the list start to the next buffer
       
   342 		iFreeBuffers = nextFree;
       
   343 	    }
       
   344 	iFreeBuffers = 0;
       
   345 	LOGTEXT(_L("CProfilerSampleStream::EmptyBuffers - exit"));
       
   346     }
       
   347 
       
   348 inline TBapBuf* CProfilerSampleStream::GetNextFreeBuffer()
       
   349     {
       
   350     LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - entry"));
       
   351 
       
   352 	// get a new buffer from the free buffers list
       
   353 	TBapBuf* nextFree = iFreeBuffers;
       
   354 	
       
   355 	// check if we got a buffer or not
       
   356 	if(nextFree == 0)
       
   357 	    {
       
   358 		// if there are no free buffers,
       
   359 		// create a new one
       
   360 		LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - creating new buffer"));
       
   361 		TBapBuf* newBuf = (TBapBuf*)User::Alloc(sizeof(TBapBuf));
       
   362 		if(newBuf != 0)
       
   363 		    {
       
   364 			newBuf->iBuffer = (TUint8*)User::Alloc(iBufferSize);
       
   365 			if(newBuf->iBuffer != 0)
       
   366 			    {
       
   367 				newBuf->iBufferSize = iBufferSize;
       
   368 				newBuf->iDataSize = 0;
       
   369 				newBuf->iNext = 0;
       
   370 				newBuf->iDes = new TPtr8((TUint8*)newBuf,sizeof(TBapBuf));
       
   371 				newBuf->iDes->SetLength(sizeof(TBapBuf));
       
   372 				newBuf->iBufDes = new TPtr8((TUint8*)newBuf->iBuffer,iBufferSize);
       
   373 				newBuf->iBufDes->SetLength(iBufferSize);
       
   374 				nextFree = newBuf;
       
   375 			    }
       
   376 			else
       
   377 			    {
       
   378 				LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (1)!!"));
       
   379 				return 0;
       
   380 			    }
       
   381 		    }
       
   382 		else
       
   383 		    {
       
   384 			LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - Out of memory (2)!!"));
       
   385 			delete newBuf;
       
   386 			return 0;
       
   387 		    }		
       
   388 	    }
       
   389 	else
       
   390 	    {
       
   391 		// set the list to point to next free buffer
       
   392 		iFreeBuffers = nextFree->iNext;
       
   393 	    }
       
   394 
       
   395 	LOGTEXT(_L("CProfilerSampleStream::GetNextFreeBuffer - exit"));
       
   396 	return nextFree;
       
   397     }
       
   398 
       
   399 inline void CProfilerSampleStream::AddToFilledBuffers(TBapBuf* aFilledBuffer)
       
   400     {
       
   401     LOGSTRING2("CProfilerSampleStream::AddToFilledBuffers - entry, size %d", aFilledBuffer->iDataSize);
       
   402 
       
   403     // add this buffer to the list of filled buffers
       
   404     if(iFilledBuffers == 0)
       
   405         {
       
   406         // the list is empty, so add the the beginning of the list
       
   407         // there is no next buffer in the list at the moment
       
   408         aFilledBuffer->iNext = 0;
       
   409         iFilledBuffers = aFilledBuffer;
       
   410         }
       
   411     else
       
   412         {
       
   413         // there are buffers in the list, add this buffer to the beginning of the list
       
   414         aFilledBuffer->iNext = iFilledBuffers;
       
   415         iFilledBuffers = aFilledBuffer;
       
   416         }
       
   417     LOGTEXT(_L("CProfilerSampleStream::AddToFilledBuffers - exit"));
       
   418     }
       
   419 
       
   420 TBapBuf* CProfilerSampleStream::GetNextFilledBuffer()
       
   421     {
       
   422     LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - entry"));
       
   423 
       
   424     if(iFilledBuffers == 0)
       
   425         {
       
   426         // there are no filled buffers in the list
       
   427         LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - no filled bufs"));
       
   428         return 0;
       
   429         }
       
   430     else
       
   431         {   
       
   432         // get a buffer from the end of the list
       
   433         TBapBuf* buf = iFilledBuffers;
       
   434         TBapBuf* prev = 0;
       
   435 
       
   436         if(buf->iNext == 0)
       
   437             {
       
   438             // this was the last (and only) buffer
       
   439             iFilledBuffers = 0;
       
   440             LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - last filled"));
       
   441             return buf;
       
   442             }
       
   443         else
       
   444             {
       
   445             LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - searching last filled"));
       
   446             while(buf->iNext != 0)
       
   447                 {
       
   448                 // there are two or more buffers in the list
       
   449                 // proceed until the end of the list is found
       
   450                 prev = buf;
       
   451                 buf = buf->iNext;
       
   452                 }
       
   453             // now buf->next is 0, return buf and set the next
       
   454             // element of prev to NULL
       
   455             prev->iNext = 0;
       
   456             LOGTEXT(_L("CProfilerSampleStream::GetNextFilledBuffer - found last"));
       
   457             return buf;
       
   458             }
       
   459         }
       
   460     }
       
   461 
       
   462 inline void CProfilerSampleStream::AddToFreeBuffers(TBapBuf* aFreeBuffer)
       
   463     {
       
   464 	LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - entry"));
       
   465 
       
   466 	// set data size of the buffer to 0
       
   467 	aFreeBuffer->iDataSize = 0;
       
   468 
       
   469 	// add this buffer to the list of free buffers
       
   470 	if(iFreeBuffers == 0)
       
   471 	    {
       
   472 		// this is the first buffer, so set the next to point to NULL
       
   473 	    aFreeBuffer->iNext = 0;
       
   474 	    }
       
   475 	else
       
   476 	    {
       
   477 		// otherwise set to point to the beginning of the list
       
   478 	    aFreeBuffer->iNext = iFreeBuffers;
       
   479 	    }
       
   480 
       
   481 	// set this buffer to be the first one in the list
       
   482 	iFreeBuffers = aFreeBuffer;
       
   483 
       
   484 	LOGTEXT(_L("CProfilerSampleStream::AddToFreeBuffers - exit"));
       
   485     }
       
   486 
       
   487 void CProfilerSampleStream::NotifyWriter()
       
   488     {
       
   489     // notify writer plugin to write data from filled buffer list
       
   490     LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - entry"));
       
   491     iWriter->WriteData();
       
   492     LOGTEXT(_L("CProfilerSampleStream::NotifyWriter() - exit"));
       
   493     }
       
   494 
       
   495 // end of file
       
   496 
       
   497 
       
   498