perfsrv/piprofiler/plugins/GeneralsPlugin/src/IttSamplerImpl.cpp
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
equal deleted inserted replaced
56:aa2539c91954 62:1c2bb2fc7c87
    34  *  	
    34  *  	
    35  */
    35  */
    36 IttSamplerImpl::IttSamplerImpl():
    36 IttSamplerImpl::IttSamplerImpl():
    37         sampleDescriptor(&(this->sample[1]),0,KITTSampleBufferSize)
    37         sampleDescriptor(&(this->sample[1]),0,KITTSampleBufferSize)
    38 {
    38 {
    39 	this->currentLibCount = 0;
    39 	iCurrentLibCount = 0;
    40 	iTimeToSample = EFalse;
    40 	iLibsCount = 0;
       
    41 	iCodeSegsCount = 0;
       
    42 	iTimeToSample = ETrue;
       
    43 	iInitState = KIttHandlingLibs;
    41 	this->Reset();
    44 	this->Reset();
    42 }
    45 }
    43 
    46 
    44 /*
    47 /*
    45  * destructor
    48  * destructor
    46  */
    49  */
    47 IttSamplerImpl::~IttSamplerImpl()
    50 IttSamplerImpl::~IttSamplerImpl()
    48 {
    51 {
    49 
    52     LOGSTRING("IttSamplerImpl::~IttSamplerImpl()");
    50 }
    53 }
    51 
    54 
    52 /*
    55 /*
    53  * IttSamplerImpl::CreateFirstSample()
    56  * IttSamplerImpl::CreateFirstSample()
    54  * 
    57  * 
    55  * Function for creating the first sample to the log file
    58  * Function for creating the first sample to the log file
    56  */
    59  */
    57 TInt IttSamplerImpl::CreateFirstSample() 
    60 TInt IttSamplerImpl::CreateFirstSample() 
    58 {	
    61 {	
    59     Kern::Printf("ittSamplerImpl::createFirstSample\n");
       
    60 	this->iVersionData.Zero();
    62 	this->iVersionData.Zero();
    61 	this->iVersionData.Append(_L8("Bappea_ITT_V"));
    63 	this->iVersionData.Append(_L8("Bappea_ITT_V"));
    62 	this->iVersionData.Append(KIttVersion);
    64 	this->iVersionData.Append(KIttVersion);
    63 	this->itt_sample = (TUint8*)iVersionData.Ptr();
    65 	this->itt_sample = (TUint8*)iVersionData.Ptr();
    64 	return iVersionData.Length();
    66 	return iVersionData.Length();
    69  * 
    71  * 
    70  * @param TUint32 Sample number
    72  * @param TUint32 Sample number
    71  * 
    73  * 
    72  */
    74  */
    73 TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
    75 TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum)
    74 {
       
    75 #ifdef ITT_EVENT_HANDLER
       
    76     iCount++;
       
    77     if (iCount <= iIttSamplingPeriod && ((iCount % iIttSamplingPeriod) == 0 || (iCount % iIttSamplingPeriodDiv2) == 0))
       
    78     {
    76     {
    79         LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount);
    77     iCount = sampleNum;
    80         iTimeToSample = true;
    78     LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount);
    81 #else
    79 
    82     // no need to do anything, always a good time to sample.
    80     if ((iCount % iIttSamplingPeriod) == 0)
    83     // Sample time filtering is done in IttSamplerImpl:SampleImpl() function
    81         {
    84 #endif
       
    85         return true;
    82         return true;
    86 #ifdef ITT_EVENT_HANDLER    
    83         }
       
    84     return false;
    87     }
    85     }
    88     else 
       
    89     {
       
    90         return false;
       
    91     }
       
    92 #endif
       
    93 }
       
    94 
    86 
    95 /*
    87 /*
    96  * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum)
    88  * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum)
    97  * 
    89  * 
    98  * @param TUint32 program counter
    90  * @param TUint32 program counter
    99  * @param TUint32 sample number
    91  * @param TUint32 sample number
   100  */
    92  */
   101 TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum)
    93 TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum)
   102 {	
    94     {	
       
    95     //LOGSTRING3("IttSamplerImpl::SampleImpl pc %d samplenum %d",pc, sampleNum);
   103     // in order to avoid overloading the interrupt
    96     // in order to avoid overloading the interrupt
   104 	// only one dynamic file in each 50ms is added to the stream
    97 	// only one dynamic file in each 50ms is added to the stream
   105 	// with the application of the tool in mind, this is
    98 	// with the application of the tool in mind, this is
   106 	// a reasonable measure
    99 	// a reasonable measure
   107 
   100     TInt ret(0);
   108     // encode a process binary
   101     // encode a process binary
   109     sampleDescriptor.Zero();
   102  
   110 	// original 
   103     //sampleDescriptor.Zero();
   111 	if((sampleNum % 20) != 0) return 0;
   104     if(iTimeToSample)
   112 	if((sampleNum % 40) == 0)
   105         {
   113 	{
       
   114 		// encode a library binary
   106 		// encode a library binary
   115 		sampleDescriptor.Zero();
   107 		//sampleDescriptor.Zero();
   116 		DObjectCon* libs = Kern::Containers()[ELibrary];
   108 			if(iInitState == KIttHandlingLibs)
   117 		TInt libCount = libs->Count();
   109 		    {
   118 		
   110             if(iLibsCount < 20)
   119 		// go 20 binaries through at a time
   111                 {
   120 		for(TInt i=0;i<20;i++)
   112                 ret = HandleLibs(sampleNum);
   121 		{
   113                 iLibsCount++;
   122 			if(currentLibCount >= libCount)
   114                 while(ret == KErrAlreadyExists)
   123 			{
   115                     {
   124 				currentLibCount = 0;
   116                     ret = HandleLibs(sampleNum);
   125 			}
   117                     iLibsCount++;
   126 			
   118                     }
   127 			DLibrary* lib = (DLibrary*)(*libs)[currentLibCount];
   119                 }
   128 			currentLibCount++;
   120             else
   129 			
   121                 {
   130 			DCodeSeg* seg = lib->iCodeSeg;
   122                 iLibsCount = 0;
   131 			if(seg != 0)
   123                 return 0;
   132 			{
   124                 }
   133 				if( (seg->iMark & 0x80) == 0)
   125             }
   134 				{
   126 		//LOGSTRING2("IttSamplerImpl::SampleImpl HandledLibs %d", ret);
   135 					this->sample[0] = seg->iFileName->Length();
   127 		// one library has been read to sample, needs to be written to file
   136 					sampleDescriptor.Append(*(seg->iFileName));
   128 
   137 					sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
   129 		else if(iInitState == KIttHandlingCodeSegs)
   138 					sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
   130 		    {
       
   131 		    if(iCodeSegsCount < 20)
       
   132 		        {
       
   133 		        ret = HandleSegs(sampleNum);
       
   134 		        iCodeSegsCount++;
       
   135                 while(ret == KErrAlreadyExists)
       
   136                     {
       
   137                     ret = HandleSegs(sampleNum);
       
   138                     iCodeSegsCount++;
       
   139                     }
       
   140 		        }
       
   141 		    
       
   142 		    else
       
   143 		        {
       
   144 		        iCodeSegsCount = 0;
       
   145 		        return 0;
       
   146 		        }
       
   147 		    }
       
   148 
       
   149 		//LOGSTRING2("IttSamplerImpl::SampleImpl HandledSegs %d", ret);
       
   150 		else
       
   151 		    {
       
   152 		    // nothing to do
       
   153 		    Kern::Printf("IttSamplerImpl::SampleImpl - should not be here");
       
   154 		    return 0;
       
   155 		    }
       
   156         }
       
   157     else
       
   158         {
       
   159         LOGSTRING("IttSamplerImpl::SampleImpl Not time to sample");
       
   160 	}
       
   161 
       
   162 	return ret;
       
   163 }
       
   164 
       
   165 /*
       
   166  * IttSamplerImpl::Reset()
       
   167  */
       
   168 void IttSamplerImpl::Reset()
       
   169     {
       
   170     iTimeToSample = ETrue;
   139 #ifdef ITT_EVENT_HANDLER
   171 #ifdef ITT_EVENT_HANDLER
   140 					sampleDescriptor.Append((TUint8*)&(sampleNum),4);
   172     iInitialLibsTaken= EFalse;
   141 					//Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
   173     iInitialSegsTaken= EFalse;
   142 					this->iFirstSampleTaken = ETrue;
       
   143 #else
       
   144 		            //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
       
   145 #endif
   174 #endif
   146 					seg->iMark = (seg->iMark | 0x80);
   175 	iCurrentLibCount = 0;
   147 					
   176 	iLibsCount = 0;
   148 					this->sample[0] = sampleDescriptor.Size();
   177 	iCodeSegsCount = 0;
   149 					return sampleDescriptor.Size()+1;
   178 	iLatestCodeseg = NULL;
   150 				}
       
   151 			}
       
   152 		}
       
   153 	} else
       
   154 	{
       
   155 		SDblQue* codeSegList = Kern::CodeSegList();
       
   156 		//Kern::Printf("PI");
       
   157 		//TUint c = 0;
       
   158 		// the global list
       
   159 		for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
       
   160 		{				
       
   161 			DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink);
       
   162 			if(seg != 0)
       
   163 			{
       
   164 				if( (seg->iMark & 0x80) == 0)
       
   165 				{
       
   166 					this->sample[0] = seg->iFileName->Length();
       
   167 					sampleDescriptor.Append(*(seg->iFileName));
       
   168 					sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
       
   169 					sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
       
   170 #ifdef ITT_EVENT_HANDLER
       
   171                     sampleDescriptor.Append((TUint8*)&(sampleNum),4);
       
   172                     //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   173                     this->iFirstSampleTaken = ETrue;                    
       
   174 #else
       
   175 					//Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   176 #endif					
       
   177 					seg->iMark = (seg->iMark | 0x80);
       
   178 					
       
   179 					this->sample[0] = sampleDescriptor.Size();
       
   180 					return sampleDescriptor.Size()+1;
       
   181 				}
       
   182 			}
       
   183 		}	
       
   184 	}
       
   185 	return 0;
       
   186 }
       
   187 
       
   188 /*
       
   189  * IttSamplerImpl::Reset()
       
   190  */
       
   191 void IttSamplerImpl::Reset()
       
   192 {
       
   193     iTimeToSample = EFalse;
       
   194 #ifdef ITT_EVENT_HANDLER
       
   195     iFirstSampleTaken = EFalse;
       
   196 #endif
       
   197 	this->currentLibCount = 0;
       
   198 	this->itt_sample = (TUint8*)&(this->sample[0]);
   179 	this->itt_sample = (TUint8*)&(this->sample[0]);
   199 	sampleDescriptor.Zero();
   180 	sampleDescriptor.Zero();
   200 
   181 
   201 //	#ifdef ITT_TEST	
   182 //	#ifdef ITT_TEST	
   202 	SDblQue* codeSegList = Kern::CodeSegList();
   183 	SDblQue* codeSegList = Kern::CodeSegList();
   203 	// the global list
   184 	// the global list
   204 	for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
   185 	for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext)
   205 	{				
   186 	    {				
   206 		DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink);
   187 		DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink);
   207 		//if(seg != 0)
   188 		//if(seg != 0)
   208 		{
   189             {
   209 			if( (seg->iMark & 0x80) > 0)
   190 			if( (seg->iMark & 0x80) > 0)
   210 			{
   191 			    {
   211 				seg->iMark = (seg->iMark & ~0x80);
   192 				seg->iMark = (seg->iMark & ~0x80);
   212 			}
   193 			    }
   213 		}
   194             }
   214 	}	
   195 	    }	
   215 	// the garbage list
   196 	// the garbage list
       
   197 	
       
   198 	NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
   216 	DObjectCon* libs = Kern::Containers()[ELibrary];
   199 	DObjectCon* libs = Kern::Containers()[ELibrary];
       
   200 	libs->Wait();
   217 	TInt libCount = libs->Count();
   201 	TInt libCount = libs->Count();
   218 	for(TInt i=0;i<libCount;i++)
   202 	for(TInt i=0;i<libCount;i++)
   219 	{
   203 	    {
   220 		DLibrary* lib = (DLibrary*)(*libs)[i];
   204 		DLibrary* lib = (DLibrary*)(*libs)[i];
   221 		DCodeSeg* seg = lib->iCodeSeg;
   205 		DCodeSeg* seg = lib->iCodeSeg;
   222 		if( (seg->iMark & 0x80) > 0)
   206 		if( (seg->iMark & 0x80) > 0)
   223 		{
   207 		    {
   224 			seg->iMark = (seg->iMark & ~0x80);
   208 			seg->iMark = (seg->iMark & ~0x80);
   225 		}
   209 		    }
   226 	}
   210 	    }
   227 	
   211     libs->Signal();
   228 	DObjectCon* procs = Kern::Containers()[EProcess];
   212 	NKern::ThreadLeaveCS();
   229 	TInt procCount = procs->Count();
       
   230 	for(TInt i=0;i<procCount;i++)
       
   231 	{
       
   232 		DProcess* pro = (DProcess*)(*procs)[i];
       
   233 		DCodeSeg* seg = pro->iCodeSeg;
       
   234 		if(seg != 0)
       
   235 		{
       
   236 			if( (seg->iMark & 0x80) > 0)
       
   237 			{
       
   238 				seg->iMark = (seg->iMark & ~0x80);
       
   239 			}
       
   240 		}
       
   241 	}
       
   242 	//#endif   //ITT_TEST
   213 	//#endif   //ITT_TEST
   243 }
   214 }
       
   215 /*
       
   216  * 
       
   217  */
       
   218 TInt IttSamplerImpl::HandleLibs(TUint32 sampleNum)
       
   219     {
       
   220     NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex
       
   221     DObjectCon* libs = Kern::Containers()[ELibrary];
       
   222     libs->Wait();
       
   223     TInt libCount(libs->Count());
       
   224     sampleDescriptor.Zero();
       
   225     
       
   226     // go 20 binaries through at a time
       
   227     //for(TInt i=0;i<libCount;i++)
       
   228     if (iCurrentLibCount < libCount)
       
   229         {
       
   230         // get libs from 
       
   231         DLibrary* lib = (DLibrary*)(*libs)[iCurrentLibCount];
       
   232         libs->Signal();
       
   233         NKern::ThreadLeaveCS();
       
   234         iCurrentLibCount++;
       
   235         
       
   236         DCodeSeg* seg = lib->iCodeSeg;
       
   237         if(seg != 0)
       
   238             {
       
   239             if( (seg->iMark & 0x80) == 0)
       
   240                 {
       
   241                 this->sample[0] = seg->iFileName->Length();
       
   242                 sampleDescriptor.Append(*(seg->iFileName));
       
   243                 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
       
   244                 sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
       
   245 
       
   246 #ifdef ITT_EVENT_HANDLER
       
   247                 sampleDescriptor.Append((TUint8*)&(sampleNum),4);
       
   248                 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   249                 //this->iFirstSampleTaken = ETrue;
       
   250 #else
       
   251                 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize);
       
   252 #endif
       
   253                 seg->iMark = (seg->iMark | 0x80);
       
   254                 this->sample[0] = sampleDescriptor.Size();
       
   255                 return sampleDescriptor.Size()+1;
       
   256                 }
       
   257             else 
       
   258                 {
       
   259                 //Kern::Printf("Already met DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   260                 return KErrAlreadyExists;
       
   261                 }
       
   262             }
       
   263         }
       
   264     else
       
   265         {
       
   266         // check if list gone through
       
   267         iInitState = KIttHandlingCodeSegs;
       
   268         iInitialLibsTaken = ETrue;
       
   269         }
       
   270     libs->Signal();
       
   271     NKern::ThreadLeaveCS();
       
   272     return 0;
       
   273     }
       
   274 /*
       
   275  * 
       
   276  */
       
   277 TInt IttSamplerImpl::HandleSegs(TUint32 sampleNum)
       
   278     {
       
   279     SDblQue* codeSegList = Kern::CodeSegList();
       
   280     //Kern::Printf("PI");
       
   281     TUint count(0);
       
   282     sampleDescriptor.Zero();
       
   283     if(iLatestCodeseg == NULL)
       
   284         {
       
   285         iLatestCodeseg = codeSegList->First();
       
   286         }
       
   287     else
       
   288         {
       
   289         iLatestCodeseg = iLatestCodeseg->iNext;
       
   290         }
       
   291     
       
   292     // search the global code segment list
       
   293     //for (; iLatestCodeseg!=(SDblQueLink*) codeSegList; iLatestCodeseg=iLatestCodeseg->iNext)
       
   294     if (iLatestCodeseg != (SDblQueLink*) codeSegList)
       
   295         {             
       
   296         DCodeSeg* seg = _LOFF(iLatestCodeseg, DCodeSeg, iLink);
       
   297         if(seg != 0)
       
   298             {
       
   299             if( (seg->iMark & 0x80) == 0)
       
   300                 {
       
   301                 this->sample[0] = seg->iFileName->Length();
       
   302                 sampleDescriptor.Append(*(seg->iFileName));
       
   303                 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4);
       
   304                 sampleDescriptor.Append((TUint8*)&(seg->iSize),4);
       
   305 #ifdef ITT_EVENT_HANDLER
       
   306                 sampleDescriptor.Append((TUint8*)&(sampleNum),4);
       
   307                 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   308 #else
       
   309                 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   310 #endif                  
       
   311                 seg->iMark = (seg->iMark | 0x80);
       
   312                 count++;
       
   313                 this->sample[0] = sampleDescriptor.Size();
       
   314                 return sampleDescriptor.Size()+1;
       
   315                 }
       
   316             else 
       
   317                 {
       
   318                 //Kern::Printf("Already met EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum);
       
   319                 return KErrAlreadyExists;
       
   320                 }
       
   321             }
       
   322         }
       
   323     // check if list gone through
       
   324     else //if (count == 0)
       
   325         {
       
   326         iInitialSegsTaken = ETrue;
       
   327         iTimeToSample = false;
       
   328         LOGSTRING("ITT sampler - all initial samples generated!");
       
   329         }
       
   330     return 0;
       
   331     }
       
   332 
   244 // end of file
   333 // end of file