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