piprofiler/piprofiler_plat/inc/ProfilerGenericClassesKrn.inl
branchRCL_3
changeset 13 da2cedce4920
equal deleted inserted replaced
12:d27dfa8884ad 13:da2cedce4920
       
     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 <kern_priv.h>
       
    20 
       
    21 #include <piprofiler/ProfilerGenericClassesKrn.h>
       
    22 
       
    23 
       
    24 /*
       
    25  *	
       
    26  *	Class CProfilerSamplerBase implementation
       
    27  *
       
    28  */
       
    29 
       
    30 inline DProfilerSamplerBase::DProfilerSamplerBase()
       
    31     {
       
    32 	
       
    33     }
       
    34 
       
    35 inline DProfilerSamplerBase::~DProfilerSamplerBase()
       
    36     {
       
    37 	
       
    38     }
       
    39 
       
    40 /*
       
    41  *	
       
    42  *	Class CProfilerSampleBuffer implementation
       
    43  *
       
    44  */
       
    45 
       
    46 inline DProfilerSampleBuffer::DProfilerSampleBuffer(TUint8* aBuffer, 
       
    47 											TUint8* aDblBuffer, 
       
    48 											TUint32 aBufferSize )
       
    49     {
       
    50 	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer AtFirst: b:0x%x db:0x%x",aBuffer,aDblBuffer);
       
    51 
       
    52 	// make sure the alignment is right
       
    53 	if((((TUint32)aBuffer) %4) != 0)
       
    54 	    aBuffer += (4-(((TUint32)aBuffer)%4));
       
    55 	if((((TUint32)aDblBuffer) %4) != 0)
       
    56 	    aDblBuffer += (4-(((TUint32)aDblBuffer)%4));
       
    57 
       
    58 	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer b:0x%x db:0x%x",aBuffer,aDblBuffer);
       
    59 
       
    60 	iBufStruct = (TProfilerSampleBufStruct*)aBuffer;
       
    61 	iDblBufStruct = (TProfilerSampleBufStruct*)aDblBuffer;
       
    62 
       
    63 	LOGSTRING3("CProfilerSampleBuffer::CProfilerSampleBuffer bufStruct rem:0x%x dbuStruct rem:0x%x",
       
    64 						&iBufStruct->iSampleRemainder,&iDblBufStruct->iSampleRemainder);
       
    65 
       
    66 	iBufferDataSize = aBufferSize-4;
       
    67 	iBufferRealSize = aBufferSize;
       
    68 
       
    69 	ClearBuffer();
       
    70     }
       
    71 
       
    72 inline DProfilerSampleBuffer::~DProfilerSampleBuffer()
       
    73     {
       
    74 	
       
    75     }
       
    76 
       
    77 inline TInt DProfilerSampleBuffer::AddSample(TUint8* aSample, TUint32 aLength)
       
    78     {
       
    79 	TUint32 bytesTotal;
       
    80 
       
    81 	// check whether the buffer status is
       
    82 	switch (iBufferStatus)
       
    83 	    {
       
    84 		case DProfilerSampleBuffer::BufferOk:
       
    85 			// add the data normally to the buffer
       
    86 			bytesTotal = iBytesWritten+aLength;
       
    87 
       
    88 			if(bytesTotal < iBufferDataSize)
       
    89 			    {
       
    90 				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
       
    91 				iBytesWritten+=aLength;
       
    92 				return 0;
       
    93 			    }
       
    94 			else
       
    95 			    {
       
    96 
       
    97 				// the sample does not fit to the buffer
       
    98 				// first copy as much data as we can fit to the first buffer
       
    99 				TUint32 fitsToBuffer = iBufferDataSize-iBytesWritten;
       
   100 				TUint32 remaining = aLength-fitsToBuffer;
       
   101 
       
   102 				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,fitsToBuffer);
       
   103 				iBytesWritten = iBufferDataSize;
       
   104 
       
   105 				// ->switch to the double buffer
       
   106 				iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
       
   107 				
       
   108 				TProfilerSampleBufStruct* tmpPtr = iBufStruct;
       
   109 				iBufStruct = iDblBufStruct;
       
   110 				iDblBufStruct = tmpPtr;
       
   111 				
       
   112 				iDblBytesWritten = iBytesWritten;
       
   113 
       
   114 				// and this is the remainder of a sample
       
   115 				// that will be copied to the new buffer
       
   116 				// just in a while
       
   117 				iBufStruct->iSampleRemainder = remaining;
       
   118 				
       
   119 				// now that the buffers have been switched
       
   120 				// add the rest of the sample to the buffer
       
   121 				aSample+=fitsToBuffer;
       
   122 
       
   123 				// there should be room - in case the single sample
       
   124 				// is smaller than the whole buffer! so we don't
       
   125 				// bother to check
       
   126 
       
   127 				memcpy((&(iBufStruct->iDataStart)),aSample,remaining);
       
   128 				iBytesWritten = remaining;
       
   129 				return 0;
       
   130 			    }
       
   131 
       
   132 		case DProfilerSampleBuffer::BufferCopyAsap:
       
   133 
       
   134 			// no difference to the BufferOk case
       
   135 			// unless the double buffer gets filled
       
   136 			// before the data has been copied
       
   137 			// add the data normally to the buffer
       
   138 			bytesTotal = iBytesWritten+aLength;
       
   139 
       
   140 			if(bytesTotal < iBufferDataSize)
       
   141 			    {
       
   142 				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
       
   143 				iBytesWritten+=aLength;
       
   144 				return 0;
       
   145 			    }
       
   146 			else
       
   147 			    {
       
   148 				// the double buffer is now also full - there is no
       
   149 				// place to put the data -> we have to waste it!
       
   150 				// this is an indication of a too small buffer size
       
   151 				iBufferStatus = DProfilerSampleBuffer::BufferFull;
       
   152 				LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full1!!");
       
   153 				return -1;
       
   154 			    }
       
   155 
       
   156 		case DProfilerSampleBuffer::BufferBeingCopied:
       
   157 
       
   158 			// no difference to the BufferCopyAsap case
       
   159 			bytesTotal = iBytesWritten+aLength;
       
   160 
       
   161 			if(bytesTotal < iBufferDataSize)
       
   162 			    {
       
   163 				memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength);
       
   164 				iBytesWritten+=aLength;
       
   165 				return 0;
       
   166 			    }
       
   167 			else
       
   168 			    {
       
   169 				// the double buffer is now also full - there is no
       
   170 				// place to put the data -> we have to waste it!
       
   171 				// this is an indication of a too small buffer size
       
   172                 LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full2!!");
       
   173 				
       
   174 				// don't change the state to CProfilerSampleBuffer::BufferFull, since it is
       
   175 				// already being copied
       
   176 				return -1;
       
   177 			    }
       
   178 
       
   179 		case DProfilerSampleBuffer::BufferFull:
       
   180 			// the buffer is still full, there is noting we can do
       
   181 			// about it -> return
       
   182 		    LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full3!!");
       
   183 			return -1;
       
   184 
       
   185 		default:
       
   186 		    LOGSTRING("DProfilerSampleBuffer::AddSample - wrong switch!!");
       
   187 			return -1;
       
   188 	    }
       
   189     }
       
   190 
       
   191 inline void DProfilerSampleBuffer::EndSampling()
       
   192     {
       
   193     LOGSTRING("DProfilerSampleBuffer::EndSampling");
       
   194 	// this will switch to the dbl buffer even though
       
   195 	// the buffer is not full, so that data can be copied
       
   196 
       
   197 	// during this operation, no other buffer
       
   198 	// operations are allowed
       
   199 
       
   200 	// ensure that the normal buffer is in use and that the
       
   201 	// buffer is in normal state ( this procedure is performed only once )
       
   202 	if(iBufferStatus == DProfilerSampleBuffer::BufferOk)
       
   203 	    {
       
   204 		// ->switch to the double buffer
       
   205         LOGSTRING("DProfilerSampleBuffer::EndSampling - switching to double buffer");
       
   206 		iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap;
       
   207 		
       
   208 		TProfilerSampleBufStruct* tmpPtr = iBufStruct;
       
   209 		iBufStruct = iDblBufStruct;
       
   210 		iDblBufStruct = tmpPtr;
       
   211 				
       
   212 		iDblBytesWritten = iBytesWritten;
       
   213 		
       
   214 		// there is no new sample so the remainder is
       
   215 		// zero, (this shouldn't be used anyway)
       
   216 		iBufStruct->iSampleRemainder = 0;
       
   217 	    }
       
   218     }
       
   219 
       
   220 inline TUint32 DProfilerSampleBuffer::GetBufferStatus()
       
   221     {
       
   222 	return iBufferStatus;
       
   223     }
       
   224 
       
   225 inline void DProfilerSampleBuffer::ClearBuffer()
       
   226     {
       
   227 	LOGSTRING2("CProfilerSampleBuffer::ClearBuffer - %d",iBufferDataSize);
       
   228 
       
   229 	// the buffers are of same size
       
   230 	TUint8* ptr1 = (TUint8*)&(iBufStruct->iDataStart);
       
   231 	TUint8* ptr2 = (TUint8*)&(iDblBufStruct->iDataStart);
       
   232 
       
   233 	for(TUint32 i=0;i<iBufferDataSize;i++)
       
   234 	    {
       
   235 		ptr1[i] = 0;
       
   236 		ptr2[i] = 0;
       
   237 	    }
       
   238 
       
   239 
       
   240 	iBufStruct->iSampleRemainder = 0;
       
   241 	iDblBufStruct->iSampleRemainder = 0;
       
   242 
       
   243 	// written the dblBufStruct
       
   244 	iBytesWritten = 0;
       
   245 	iDblBytesWritten = 0;
       
   246 	iDblBytesRead = 0;
       
   247 
       
   248 	iBufferStatus = DProfilerSampleBuffer::BufferOk;
       
   249     }
       
   250 
       
   251 inline void DProfilerSampleBuffer::DataCopied()
       
   252     {
       
   253 	iDblBytesRead = 0;
       
   254 	iDblBytesWritten = 0;
       
   255 	iBufferStatus = DProfilerSampleBuffer::BufferOk;
       
   256     }
       
   257 
       
   258 /*
       
   259  *
       
   260  *	Class DProfilerSampleStream implementation
       
   261  *
       
   262  */
       
   263 
       
   264 inline DProfilerSampleStream::DProfilerSampleStream()
       
   265     {
       
   266 	LOGSTRING("DProfilerSampleStream::DProfilerSampleStream");
       
   267 
       
   268 	iCurrentBuffer = 0;
       
   269 	iPendingRequest = 0;
       
   270 	iAddingSamples = 0;
       
   271 	iClient = 0;
       
   272     }
       
   273 
       
   274 inline DProfilerSampleStream::~DProfilerSampleStream()
       
   275     {
       
   276 	LOGSTRING("DProfilerSampleStream::~DProfilerSampleStream");	
       
   277     }
       
   278 
       
   279 inline void DProfilerSampleStream::InsertCurrentClient(DThread* aClient)
       
   280     {
       
   281 	iClient = aClient;
       
   282 	LOGSTRING2("DProfilerSampleStream::InsertCurrentClient - iClient is 0x%x",iClient);
       
   283     }
       
   284 
       
   285 
       
   286 inline void DProfilerSampleStream::AddSampleBuffer(TBapBuf* aBuffer,TRequestStatus* aStatus)
       
   287     {
       
   288 	if(iCurrentBuffer != 0 || iPendingRequest != 0)
       
   289 	    {
       
   290 		LOGSTRING("DProfilerSampleStream::AddSampleBuffer - ERROR 1");
       
   291 		return;
       
   292 	    }
       
   293 
       
   294 	LOGSTRING3("DProfilerSampleStream::AddSampleBuffer - OK 0x%x,0x%x",aBuffer,aStatus);
       
   295 	iCurrentBuffer = aBuffer;
       
   296 	iPendingRequest = aStatus;
       
   297 	
       
   298 	LOGSTRING2("DProfilerSampleStream::AddSampleBuffer - Current Client is 0x%x",iClient);	
       
   299     }
       
   300 
       
   301 
       
   302 inline void DProfilerSampleStream::ReleaseIfPending()
       
   303     {
       
   304     LOGSTRING("DProfilerSampleStream::ReleaseIfPending - entry");
       
   305 
       
   306 	if(iCurrentBuffer != 0 && iPendingRequest != 0 && iClient != 0)
       
   307 	    {
       
   308 		LOGSTRING("DProfilerSampleStream::ReleaseIfPending - release buffer");
       
   309 
       
   310 		LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
       
   311 		Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
       
   312 		
       
   313 		iPendingRequest = 0;
       
   314 		iCurrentBuffer = 0;
       
   315 	    }
       
   316 
       
   317 	LOGSTRING("DProfilerSampleStream::ReleaseIfPending - exit");
       
   318     }
       
   319 
       
   320 inline void DProfilerSampleStream::AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId)
       
   321     {
       
   322 	LOGSTRING3("DProfilerSampleStream::AddSamples - entry ID: %d, currentbuffer: 0x%x", aSamplerId,iCurrentBuffer);
       
   323 	if(iCurrentBuffer != 0)
       
   324 	    {
       
   325 		// the following will perform simple mutual exclusion
       
   326 		iAddingSamples++;
       
   327 		if(iAddingSamples > 1) 
       
   328 		    {
       
   329 			// there is someone else adding samples to the buffer
       
   330             LOGSTRING("DProfilerSampleStream::AddSamples - mutex in use");
       
   331 			iAddingSamples--;
       
   332 			return;
       
   333 		    }
       
   334 
       
   335 		LOGSTRING("DProfilerSampleStream::AddSamples - reading TBapBuf");
       
   336 		
       
   337 		// use a copy of the client TBapBuf structure during processing
       
   338 		TBapBuf realBuf;
       
   339 		TPtr8 ptr((TUint8*)&realBuf,(TInt)sizeof(TBapBuf));
       
   340 	
       
   341 		Kern::ThreadRawRead(iClient,(TAny*)(iCurrentBuffer),(TAny*)&realBuf,sizeof(TBapBuf));
       
   342 
       
   343 		ptr.SetLength(sizeof(TBapBuf));
       
   344 
       
   345 		LOGSTRING4("DProfilerSampleStream::AddSamples - read %d bytes from 0x%x of thread 0x%x",ptr.Size(),iCurrentBuffer,iClient);
       
   346 
       
   347 		LOGSTRING5("DProfilerSampleStream::AddSamples - current buffer 0x%x -> b:0x%x s:%d d:%d",
       
   348 			&realBuf,
       
   349 			realBuf.iBuffer,
       
   350 			realBuf.iBufferSize,
       
   351 			realBuf.iDataSize);
       
   352 
       
   353 		// get the address of the source buffer data
       
   354 		TUint8* src = (TUint8*)&(aBuffer.iDblBufStruct->iDataStart);
       
   355 		src += aBuffer.iDblBytesRead;
       
   356 
       
   357 		// the amount of data to copy is the 4 header bytes +
       
   358 		// the remaining data in the buffer
       
   359 		TInt amount = aBuffer.iDblBytesWritten-aBuffer.iDblBytesRead;
       
   360 
       
   361 		TUint8* dst = realBuf.iBuffer;
       
   362 
       
   363 		LOGSTRING4("DProfilerSampleStream::AddSamples - s:0x%x d:0x%x a:%d",src,dst,amount);
       
   364 
       
   365 		if(realBuf.iDataSize == 0)
       
   366 		    {
       
   367 			LOGSTRING("DProfilerSampleStream::AddSamples - case 1");
       
   368 
       
   369 			// the buffer is empty
       
   370 			if(realBuf.iBufferSize >= (amount+4))
       
   371 			    {
       
   372 				LOGSTRING("DProfilerSampleStream::AddSamples - case 1.1");
       
   373 
       
   374 				// the source buffer is smaller or of equal size than the amount of output data
       
   375 				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
       
   376 				realBuf.iDataSize += amount+4;
       
   377 				// the rest of the source buffer was copied at once, so signal the buffer
       
   378 				aBuffer.DataCopied();
       
   379 			    }
       
   380 			else
       
   381 			    {
       
   382 				LOGSTRING("DProfilerSampleStream::AddSamples - case 1.2");
       
   383 
       
   384 				// only a part of the source buffer will fit to the client side buffer
       
   385 				amount = realBuf.iBufferSize-4;
       
   386 				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,0,amount);
       
   387 				realBuf.iDataSize += amount+4;
       
   388 				// add the amount of bytes read to the source buffer
       
   389 				aBuffer.iDblBytesRead+=amount;
       
   390 			    }
       
   391 		    }
       
   392 		else
       
   393 		    {
       
   394 			LOGSTRING("DProfilerSampleStream::AddSamples - case 2");
       
   395 
       
   396 			// there is data in the client buffer
       
   397 			dst += realBuf.iDataSize;
       
   398 			TInt remainingSpace = realBuf.iBufferSize-realBuf.iDataSize;
       
   399 
       
   400 			if( remainingSpace >= (amount+4) )
       
   401 			    {
       
   402 				LOGSTRING("DProfilerSampleStream::AddSamples - case 2.1");
       
   403 
       
   404 				// the source buffer is smaller or of equal size than the amount of output data
       
   405 				PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
       
   406 				realBuf.iDataSize += (amount+4);
       
   407 				// the rest of the source buffer was copied at once, so signal the buffer
       
   408 				aBuffer.DataCopied();
       
   409 			    }
       
   410 			else
       
   411 			    {
       
   412 				LOGSTRING("DProfilerSampleStream::AddSamples - case 2.2");
       
   413 
       
   414 				// only a part of the source buffer will fit to the client side buffer
       
   415 				if(remainingSpace >= 12)
       
   416 				    {
       
   417 					LOGSTRING("DProfilerSampleStream::AddSamples - case 2.3");
       
   418 
       
   419 					amount = remainingSpace-4;
       
   420 					// there are at least 8 bytes left for data, write it
       
   421 					PerformCopy((TUint8)aSamplerId,src,realBuf.iBufDes,realBuf.iDataSize,amount);
       
   422 					realBuf.iDataSize += (amount+4);
       
   423 					// add the amount of bytes read to the source buffer
       
   424 					aBuffer.iDblBytesRead+=amount;				
       
   425 				    }
       
   426 			    }
       
   427 		    }
       
   428 	
       
   429 		// copy the data in the modified TBapBuf structure back to the client
       
   430 		LOGSTRING("DProfilerSampleStream::AddSamples - writing TBapBuf");
       
   431 
       
   432 		Kern::ThreadDesWrite(iClient,(TAny*)(realBuf.iDes),ptr,0,KChunkShiftBy0,iClient);
       
   433 
       
   434 		// if the client side buffer is full or nearly full, signal the client
       
   435 		LOGSTRING("DProfilerSampleStream::AddSamples - data copied");
       
   436 
       
   437 		if(realBuf.iBufferSize-realBuf.iDataSize < 12)
       
   438 		    {
       
   439 			LOGSTRING("DProfilerSampleStream::AddSamples - release buffer");
       
   440 			
       
   441 			LOGSTRING2("DProfilerSampleStream::AddSamples - completing request 0x%x",iPendingRequest);
       
   442 
       
   443 			Kern::RequestComplete(iClient,iPendingRequest,KErrNone);
       
   444 
       
   445 			iPendingRequest = 0;
       
   446 			iCurrentBuffer = 0;
       
   447 			//iClient = 0;
       
   448 		    }
       
   449 
       
   450 		// free the lock
       
   451 		iAddingSamples--;
       
   452 	    }
       
   453 	LOGSTRING("DProfilerSampleStream::AddSamples - exit");
       
   454     }
       
   455 
       
   456 
       
   457 
       
   458 inline TInt DProfilerSampleStream::EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId)
       
   459     {
       
   460     LOGSTRING2("DProfilerSampleStream::EndSampling, sampler ID: %d",aSamplerId);
       
   461 
       
   462 	// switch the buffer to double buffer
       
   463 	// even though it would not be full yet
       
   464 	// the switch is done only once / end sampling procedure
       
   465 	// (Only with BufferOk status)
       
   466 	aBuffer.EndSampling();
       
   467 	
       
   468 	LOGSTRING2("DProfilerSampleStream::EndSampling, iClient: 0x%x",iClient);
       
   469 	
       
   470 	if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferDataEnd)
       
   471 	    {
       
   472 		// add these final samples to the client buffer
       
   473 		AddSamples(aBuffer,aSamplerId);
       
   474 		
       
   475 		// if all data was copied to the buffer, the buffer status is now BufferOk
       
   476 
       
   477 		if(aBuffer.iBufferStatus != DProfilerSampleBuffer::BufferOk)
       
   478 		    {
       
   479             LOGSTRING("DProfilerSampleStream::EndSampling - more data to copy");
       
   480 			// there is still more data to copy, the pending request should have been
       
   481 			// completed in AddSamples(), because the client buffer got filled 
       
   482 			return 1;
       
   483 		    }
       
   484 		else
       
   485 		    {
       
   486 			// buffer status was changed to BufferOk in AddSamples() - 
       
   487 			// this means all data from it could be copied
       
   488 			// now we have to change the status of the buffer to BufferDataEnd, so
       
   489 			// we know that the particular buffer has no more data to copy
       
   490             LOGSTRING("DProfilerSampleStream::EndSampling - switch to BufferDataEnd");
       
   491 			aBuffer.iBufferStatus = DProfilerSampleBuffer::BufferDataEnd;
       
   492 		    }
       
   493 	    }
       
   494 
       
   495 	// the buffer was completely emptied to the client buffer, or there was no
       
   496 	// data to copy to the client side
       
   497 	LOGSTRING("DProfilerSampleStream::EndSampling - no more data to copy");
       
   498 
       
   499 	return 0;
       
   500     }
       
   501 
       
   502 inline void DProfilerSampleStream::PerformCopy(TUint8 aSamplerId,TUint8* aSrc,TPtr8* aDst,TInt aOffset,TInt aAmount)
       
   503     {
       
   504 	LOGSTRING2("DProfilerSampleStream::PerformCopy for sampler ID: %d",aSamplerId);	
       
   505 	LOGSTRING5("DProfilerSampleStream::PerformCopy - 0x%x -> 0x%x - %d - offset: %d",aSrc, aDst, aAmount, aOffset);	
       
   506 	TUint32 header;
       
   507 	header = aAmount & 0x00ffffff;
       
   508 	header += (aSamplerId << 24);
       
   509 	TPtr8 ptr((TUint8*)&header,4);
       
   510 	ptr.SetLength(4);
       
   511 
       
   512 	LOGSTRING2("DProfilerSampleStream::PerformCopy - start header copy HDR = 0x%x",header);	
       
   513 
       
   514 	// write the header
       
   515 	Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
       
   516 
       
   517 	LOGSTRING2("DProfilerSampleStream::PerformCopy - copied header %d bytes",ptr.Size());	
       
   518 	aOffset+=4;
       
   519 
       
   520 	LOGSTRING("DProfilerSampleStream::PerformCopy - start copy");	
       
   521 	// write the data
       
   522 	ptr.Set(aSrc,aAmount,aAmount);
       
   523 	ptr.SetLength(aAmount);
       
   524 	
       
   525 	Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0);
       
   526 
       
   527 
       
   528 	LOGSTRING2("DProfilerSampleStream::PerformCopy - copied data %d bytes",ptr.Size());	
       
   529 
       
   530     }