piprofiler/plugins/GeneralsPlugin/inc/GfcSamplerImpl.h
branchRCL_3
changeset 13 da2cedce4920
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/GeneralsPlugin/inc/GfcSamplerImpl.h	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,249 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+#ifndef PROFILER_GFC_SAMPLER_H
+#define PROFILER_GFC_SAMPLER_H
+
+
+#include "GeneralsConfig.h"
+
+#include <kern_priv.h>
+
+#include <piprofiler/ProfilerGenericClassesKrn.h>
+#include <piprofiler/ProfilerTraces.h>
+#include "GppSamplerImpl.h"
+
+extern void UsrModLr(TUint32*);
+
+
+/*
+ *	
+ *	GFC sampler definition
+ *	
+ */
+
+template <int BufferSize>
+class DProfilerGfcSampler : public DProfilerGenericSampler<BufferSize>
+{
+public:
+	DProfilerGfcSampler(struct TProfilerGppSamplerData* );
+	~DProfilerGfcSampler();
+
+	void	Sample();
+	TInt	Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset);
+private:
+	struct TProfilerGppSamplerData* gppSamplerData;
+	TUint32 gfcSample[3];
+
+	TUint8	encodedSample[15];
+	TUint32	repeat;
+};
+
+/*
+ *	
+ *	GFC sampler implementation
+ *	
+ */
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::DProfilerGfcSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) :
+	DProfilerGenericSampler<BufferSize>(PROFILER_GFC_SAMPLER_ID)
+{
+	this->gppSamplerData = gppSamplerDataIn;
+	LOGSTRING2("CProfilerGfcSampler<%d>::CProfilerGfcSampler",BufferSize);	
+}
+
+template <int BufferSize>
+TInt DProfilerGfcSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset)
+{
+	LOGSTRING2("CProfilerGfcSampler<BufferSize> - entry",BufferSize);
+	
+	this->repeat = 0;
+	for(TInt i(0);i<3;i++)
+	{
+		this->gfcSample[i] = 0;
+	}
+
+	LOGSTRING2("CProfilerGfcSampler<%d>::Reset - calling superclass reset",BufferSize);
+	DProfilerGenericSampler<BufferSize>::Reset(aStream);
+	LOGSTRING2("CProfilerGfcSampler<%d>::Reset - called superclass reset",BufferSize);
+	
+	// add the first sample, indicating the gfc trace version
+	TUint8 firstSample[33];
+	TPtr8 firstSampleDesc(&(firstSample[1]),32);
+	firstSampleDesc.Zero();
+
+	firstSampleDesc.Append(_L8("Bappea_V"));
+	firstSampleDesc.Append(PROFILER_GFC_SAMPLER_VERSION);
+	firstSampleDesc.Append(_L8("_GFC"));
+	firstSample[0] = firstSampleDesc.Size();
+
+	this->iSampleBuffer->AddSample(firstSample,(firstSample[0]+1));
+
+	LOGSTRING2("CProfilerGfcSampler<BufferSize> - exit",BufferSize);
+
+	return KErrNone;
+}
+
+template <int BufferSize>
+void DProfilerGfcSampler<BufferSize>::Sample()
+{
+	LOGSTRING2("CProfilerGfcSampler<%d>::Sample",BufferSize);	
+
+	TUint32 usr_mod_link_reg;
+
+	UsrModLr(&usr_mod_link_reg);
+
+	TUint32 pc(gppSamplerData->lastPcValue);
+	TUint32 lr(usr_mod_link_reg);
+	TUint32 sa(gppSamplerData->sampleNumber);
+
+	if(pc == gfcSample[0] && lr == gfcSample[1] && sa == gfcSample[2]+1)
+	{
+		// encode repeat
+		repeat++;
+		gfcSample[2] = sa;
+		LOGSTRING2("CProfilerGfcSampler<%d>::Sample - repeat",BufferSize);
+		return;
+	}
+	else if(repeat > 0)
+	{
+		TUint8 repeatSample[3];
+		repeatSample[0] = 0xff;
+		repeatSample[1] = (TUint8)(repeat>>8);
+		repeatSample[2] = (TUint8)repeat;
+		this->iSampleBuffer->AddSample(repeatSample,3);
+
+		LOGSTRING3("CProfilerGfcSampler<%d>::Sample - Encoded repeat %d",BufferSize,repeat);
+
+		repeat = 0;
+	}
+
+	TInt ptr(3);
+
+	// encode program counter value
+	if(pc>=gfcSample[0]) 
+	{
+		pc = (pc-gfcSample[0]);
+		encodedSample[0] = 0x80;
+	}
+	else 
+	{
+		pc = (gfcSample[0]-pc);
+		encodedSample[0] = 0x00;
+	}
+
+	if(pc <= (TUint32)0xff) 
+	{
+		encodedSample[0] |= 1;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+	}
+	else if(pc <= (TUint32)0xffff) 
+	{
+		encodedSample[0] |= 2;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+	}
+	else if(pc <= (TUint32)0xffffff) 
+	{
+		encodedSample[0] |= 3;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+	}
+	else 
+	{
+		encodedSample[0] |= 4;
+		encodedSample[ptr] = (TUint8)pc;ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(pc>>24);ptr++;
+	}
+
+	// encode link register value
+	if(lr>=gfcSample[1]) 
+	{
+		lr = (lr-gfcSample[1]);
+		encodedSample[1] = 0x80;
+	}
+	else 
+	{
+		lr = (gfcSample[1]-lr);
+		encodedSample[1] = 0x00;
+	}
+
+	if(lr <= (TUint32)0xff) 
+	{
+		encodedSample[1] |= 1;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+	}
+	else if(lr <= (TUint32)0xffff) 
+	{
+		encodedSample[1] |= 2;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+	}
+	else if(lr <= (TUint32)0xffffff) 
+	{
+		encodedSample[1] |= 3;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+	}
+	else 
+	{
+		encodedSample[1] |= 4;
+		encodedSample[ptr] = (TUint8)lr;ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(lr>>24);ptr++;
+	}
+	
+	// endcode sample number difference
+	if( (sa - gfcSample[2]) < (TUint8)0xff) 
+	{
+		encodedSample[2] = (sa-gfcSample[2]);
+	}
+	else
+	{
+		encodedSample[2] = 0xff;
+		encodedSample[ptr] = (TUint8)sa;ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>8);ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>16);ptr++;
+		encodedSample[ptr] = (TUint8)(sa>>24);ptr++;
+	}
+
+	// store the values for the next sample
+	gfcSample[0] = gppSamplerData->lastPcValue;
+	gfcSample[1] = usr_mod_link_reg;
+	gfcSample[2] = gppSamplerData->sampleNumber;
+	
+	this->iSampleBuffer->AddSample(encodedSample,ptr);
+
+	LOGSTRING3("CProfilerGfcSampler<%d>::Sample Size %d",BufferSize,ptr);
+
+	return;
+
+}
+
+template <int BufferSize>
+DProfilerGfcSampler<BufferSize>::~DProfilerGfcSampler()
+{
+	LOGSTRING2("CProfilerGfcSampler<%d>::~CProfilerGfcSampler",BufferSize);		
+}
+#endif