sysanadatacapture/piprofiler/piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp
changeset 1 3ff3fecb12fe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysanadatacapture/piprofiler/piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp	Thu Feb 11 15:52:57 2010 +0200
@@ -0,0 +1,560 @@
+/*
+* 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:  
+*
+*/
+
+
+#include <piprofiler/ProfilerVersion.h>
+
+#include <kern_priv.h>
+#include <plat_priv.h>
+
+#include "IttSamplerImpl.h"
+
+/*
+ *	
+ *	ITT sampler definition
+ *	
+ */
+
+IttSamplerImpl::IttSamplerImpl()
+{
+	this->ptrToData = new TPtr8(((TUint8*)&(this->internalData[1])),255);
+	this->currentLibCount = 0;
+	this->currentProcCount = 0;
+	this->iSampleProcesses = false;
+
+	this->Reset();
+}
+
+IttSamplerImpl::~IttSamplerImpl()
+{
+	delete(this->ptrToData);
+}
+
+TInt IttSamplerImpl::CreateFirstSample() 
+{				
+	this->iVersionData.Zero();
+	this->iVersionData.Append(_L8("Bappea_ITT_V"));
+	this->iVersionData.Append(PROFILER_ITT_SAMPLER_VERSION);
+	this->itt_sample = (TUint8*)iVersionData.Ptr();
+	return iVersionData.Length();
+}
+
+TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
+{
+	return true;
+}
+
+TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum)
+{	
+	// in order to avoid overloading the interrupt
+	// only one dynamic file in each 50ms is added to the stream
+	// with the application of the tool in mind, this is
+	// a reasonable measure
+	
+//	#ifdef ITT_TEST
+	//if(iSampleProcesses)
+	{
+		// encode a process binary
+		ptrToData->Zero();
+		
+		//static RPointerArray<DCodeSeg> array = DCodeSeg::CodeSegsByName;
+		//TInt arrayCount = array.Count();
+		
+		/* mietintää...
+		
+		DCodeSeg* pSeg = Kern::CodeSegFromAddress( (TLinAddr)aPtr, TheCurrentThread->iOwningProcess );
+		if (!pSeg)
+			{
+	 		return KErrNotFound;
+			}
+		Kern::KUDesPut(aModuleName, *pSeg->iFileName);
+
+		// lisää pohdintaa
+		
+		TInt n=0;
+		TInt i;
+		TInt c=iDynamicCode.Count();	// DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib
+		for (i=-1; i<c; ++i)
+		{
+			DCodeSeg* pS=(i<0)?iCodeSeg:iDynamicCode[i].iSeg;
+			if (pS && pS!=aExclude)
+			{
+				if ((aFlags & ETraverseFlagRestrict) && i>=0)
+				{
+					DLibrary* pL=iDynamicCode[i].iLib;
+					if (pL && pL->iState!=DLibrary::EAttached)
+						continue;
+				}
+				if (aFlags & ETraverseFlagAdd)
+					n+=pS->ListDeps(aQ,aMark);
+				else
+					n+=pS->UnListDeps(aMark);
+			}
+		}
+		
+
+		*/
+
+/*		
+		// testi...
+		// encode a process binary
+		//Kern::Printf("Get Processes from container...");
+		DObjectCon* proc = Kern::Containers()[EProcess];
+		TInt procCount = proc->Count();
+
+		//Kern::Printf("Got count of processes: %d", procCount);
+		
+		// go 20 executables through at a time
+		for(TInt i=0;i<procCount;i++)
+		{
+			DProcess* pro = (DProcess*)(*proc)[i];
+	
+			//Kern::Printf("Inspecting DProcess array...");
+
+			TInt c=pro->iDynamicCode.Count();	// DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib
+
+			//Kern::Printf("DProcess: count of segments %d", c);
+			for (TInt i=-1; i<c; ++i)
+			{
+				DCodeSeg* seg=(i<0)?pro->iCodeSeg:pro->iDynamicCode[i].iSeg;
+				if(seg != 0)
+				{
+					if( (seg->iMark & 0x80) == 0)
+					{
+						this->internalData[0] = seg->iFileName->Length();
+						ptrToData->Append(*(seg->iFileName));
+						ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+						ptrToData->Append((TUint8*)&(seg->iSize),4);
+						//Kern::Printf("EXE1: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+						seg->iMark = (seg->iMark | 0x80);
+						
+						this->internalData[0] = ptrToData->Size();
+						return ptrToData->Size()+1;
+					}
+				}
+			}
+		}
+*/		
+/*
+		
+		DObjectCon* libs = Kern::Containers()[ELibrary];
+		TInt libCount = libs->Count();
+
+		//Kern::Printf("Got count of processes: %d", procCount);
+		
+		// go 20 executables through at a time
+		for(TInt i=0;i<libCount;i++)
+		{
+			//Kern::Printf("Inspecting DLibrary array...");
+
+			DLibrary* lib = (DLibrary*)(*libs)[i];
+			
+			DCodeSeg* seg = lib->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}		
+*/
+	// original 
+	if((sampleNum % 20) != 0) return 0;
+	if((sampleNum % 40) == 0)
+	{
+/*
+	if((sampleNum % 60) == 0)
+	{
+		// encode a process binary
+		ptrToData->Zero();
+		DObjectCon* proc = Kern::Containers()[EProcess];
+		TInt procCount = proc->Count();
+		
+		// go 20 executables through at a time
+		for(TInt i=0;i<20;i++)
+		{
+			if(currentProcCount >= procCount) 
+			{
+				currentProcCount = 0;
+			}
+			
+			DProcess* pro = (DProcess*)(*proc)[currentProcCount];
+			currentProcCount++;
+			
+			DCodeSeg* seg = pro->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}
+	}	else  
+	{ */
+		// encode a library binary
+		ptrToData->Zero();
+		DObjectCon* libs = Kern::Containers()[ELibrary];
+		TInt libCount = libs->Count();
+		
+		// go 20 binaries through at a time
+		for(TInt i=0;i<20;i++)
+		{
+			if(currentLibCount >= libCount)
+			{
+				currentLibCount = 0;
+			}
+			
+			DLibrary* lib = (DLibrary*)(*libs)[currentLibCount];
+			currentLibCount++;
+			
+			DCodeSeg* seg = lib->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}
+	} else
+	{
+		SDblQue* codeSegList = Kern::CodeSegList();
+		//Kern::Printf("PI");
+		//TUint c = 0;
+		// the global list
+		for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+		{				
+			DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink);
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}	
+	}
+
+/*
+		// the garbage list 
+		for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+		{				
+			DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iGbgLink);
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}	
+*/
+		
+		// Another try
+//	Kern::AccessCode();
+	
+	//Collect all non-XIP segments that are not already marked.
+/*
+	SDblQue* p = Kern::CodeSegList();
+	SDblQueLink* anchor=&p->iA;
+	SDblQueLink* a=anchor->iNext;
+	for (; a!=anchor; a=a->iNext) 
+	{
+		DEpocCodeSeg* pSeg = (DEpocCodeSeg*) _LOFF(a, DCodeSeg, iLink);
+		if (pSeg != 0)
+		{
+			if (pSeg->iXIP || pSeg->iMark&DCodeSeg::EMarkProfilerTAG)
+			{
+					//continue;
+				//if (current > (max-KMaxCreateCodeSegRecordSize))
+				//	break;//No more space. Finish now and wait for another GetSegments request.
+					
+				pSeg->iMark |= DCodeSeg::EMarkProfilerTAG;	//Mark this segment
+				this->internalData[0] = pSeg->iFileName->Length();
+				ptrToData->Append(*(pSeg->iFileName));
+				ptrToData->Append((TUint8*)&(pSeg->iRunAddress),4);
+				ptrToData->Append((TUint8*)&(pSeg->iSize),4);
+				//Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
+				
+				this->internalData[0] = ptrToData->Size();
+				return ptrToData->Size()+1;
+			}
+		}
+	}
+*/
+	
+//	Kern::EndAccessCode();		
+		
+		//Kern::Printf("PO");
+
+/*		
+		for(TInt i=0;i<arrayCount;i++)
+		{
+			currentProcCount++;
+			DCodeSeg* seg = (DCodeSeg*)array[i];
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}
+*/
+	}
+/*
+	#else
+	if((sampleNum % 50) != 0) return 0;
+	if((sampleNum % 100) == 0)
+	{
+		// encode a process binary
+		ptrToData->Zero();
+		DObjectCon* proc = Kern::Containers()[EProcess];
+		TInt procCount = proc->Count();
+		
+		// go 20 executables through at a time
+		for(TInt i=0;i<20;i++)
+		{
+			if(currentProcCount >= procCount) 
+			{
+				currentProcCount = 0;
+			}
+			
+			DProcess* pro = (DProcess*)(*proc)[currentProcCount];
+			currentProcCount++;
+			
+			DCodeSeg* seg = pro->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}
+	}
+	else
+	{
+		// encode a library binary
+		ptrToData->Zero();
+		DObjectCon* libs = Kern::Containers()[ELibrary];
+		TInt libCount = libs->Count();
+		
+		// go 20 binaries through at a time
+		for(TInt i=0;i<20;i++)
+		{
+			if(currentLibCount >= libCount)
+			{
+				currentLibCount = 0;
+			}
+			
+			DLibrary* lib = (DLibrary*)(*libs)[currentLibCount];
+			currentLibCount++;
+			
+			DCodeSeg* seg = lib->iCodeSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) == 0)
+				{
+					this->internalData[0] = seg->iFileName->Length();
+					ptrToData->Append(*(seg->iFileName));
+					ptrToData->Append((TUint8*)&(seg->iRunAddress),4);
+					ptrToData->Append((TUint8*)&(seg->iSize),4);
+					//Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
+					seg->iMark = (seg->iMark | 0x80);
+					
+					this->internalData[0] = ptrToData->Size();
+					return ptrToData->Size()+1;
+				}
+			}
+		}
+	}
+	#endif
+*/	
+	return 0;
+
+}
+
+void IttSamplerImpl::Reset()
+{
+	this->currentLibCount = 0;
+	this->currentProcCount = 0;
+	this->itt_sample = (TUint8*)&(this->internalData[0]);
+	ptrToData->Zero();
+
+//	#ifdef ITT_TEST	
+
+	SDblQue* codeSegList = Kern::CodeSegList();
+	// the global list
+	for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+	{				
+		DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink);
+		//if(seg != 0)
+		{
+			if( (seg->iMark & 0x80) > 0)
+			{
+				seg->iMark = (seg->iMark & ~0x80);
+			}
+		}
+	}	
+
+	// the garbage list
+/*
+	for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
+	{				
+		DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iGbgLink);
+		if(seg != 0)
+		{
+			if( (seg->iMark & 0x80) > 0)
+			{
+				seg->iMark = (seg->iMark & ~0x80);
+			}
+		}
+	}
+*/		
+// another try
+/*
+//	Kern::AccessCode();
+	SDblQue* p = Kern::CodeSegList();
+	SDblQueLink* anchor=&p->iA;
+	SDblQueLink* a=anchor->iNext;
+	for (; a!=anchor; a=a->iNext) 
+		{
+		DEpocCodeSeg* pSeg = (DEpocCodeSeg*) _LOFF(a, DCodeSeg, iLink);
+		if (!pSeg->iXIP)
+			pSeg->iMark &= ~DCodeSeg::EMarkProfilerTAG;
+		}
+
+//	Kern::EndAccessCode();
+*/
+/*
+	DObjectCon* proc = Kern::Containers()[EProcess];
+	TInt procCount = proc->Count();
+	
+	// go 20 executables through at a time
+	for(TInt i=0;i<procCount;i++)
+	{
+		DProcess* pro = (DProcess*)(*proc)[i];
+
+		//Kern::Printf("Reset: Inspecting DProcess...");
+
+		TInt c=pro->iDynamicCode.Count();	// DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib
+
+		//Kern::Printf("Reset: DProcess: count of segments %d", c);
+		for (TInt i=-1; i<c; ++i)
+		{
+			DCodeSeg* seg=(i<0)?pro->iCodeSeg:pro->iDynamicCode[i].iSeg;
+			if(seg != 0)
+			{
+				if( (seg->iMark & 0x80) > 0)
+				{
+					seg->iMark = (seg->iMark & ~0x80);
+				}
+			}
+		}
+	}
+	
+	//Kern::Printf("Reset: Exiting...");
+
+	#else
+*/
+	DObjectCon* libs = Kern::Containers()[ELibrary];
+	TInt libCount = libs->Count();
+	for(TInt i=0;i<libCount;i++)
+	{
+		DLibrary* lib = (DLibrary*)(*libs)[i];
+		DCodeSeg* seg = lib->iCodeSeg;
+		if( (seg->iMark & 0x80) > 0)
+		{
+			seg->iMark = (seg->iMark & ~0x80);
+		}
+	}
+	
+	DObjectCon* procs = Kern::Containers()[EProcess];
+	TInt procCount = procs->Count();
+	for(TInt i=0;i<procCount;i++)
+	{
+		DProcess* pro = (DProcess*)(*procs)[i];
+		DCodeSeg* seg = pro->iCodeSeg;
+		if(seg != 0)
+		{
+			if( (seg->iMark & 0x80) > 0)
+			{
+				seg->iMark = (seg->iMark & ~0x80);
+			}
+		}
+	}		
+	//#endif
+}