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