perfsrv/piprofiler/plugins/GeneralsPlugin/src/GppSamplerImpl.cpp
changeset 62 1c2bb2fc7c87
parent 51 98307c651589
equal deleted inserted replaced
56:aa2539c91954 62:1c2bb2fc7c87
    24 #include "GppSamplerImpl.h"
    24 #include "GppSamplerImpl.h"
    25 
    25 
    26 extern TUint*		IntStackPtr();
    26 extern TUint*		IntStackPtr();
    27 #define	TAG(obj)	(*(TUint32*)&(obj.iAsyncDeleteNext))
    27 #define	TAG(obj)	(*(TUint32*)&(obj.iAsyncDeleteNext))
    28 
    28 
       
    29 #ifndef __SMP__
       
    30 extern TUint IDFCRunning();
       
    31 #endif
       
    32 
       
    33 #ifdef __SMP__
       
    34 static TSpinLock CpuSpinLock = TSpinLock(TSpinLock::EOrderGenericIrqLow3);
       
    35 #endif
       
    36 
    29 // properties for ISA task parsing
    37 // properties for ISA task parsing
    30 const TUid KIsaPropertyCat={0x2001E5AD};
    38 const TUid KIsaPropertyCat={0x2001E5AD};
    31 enum TIsaPropertyKeys
    39 enum TIsaPropertyKeys
    32 	{
    40 	{
    33 	EIsaPropertyIsaTaskParserStatus = 1,
    41 	EIsaPropertyIsaTaskParserStatus = 1,
    40 
    48 
    41 
    49 
    42 DGppSamplerImpl::DGppSamplerImpl()
    50 DGppSamplerImpl::DGppSamplerImpl()
    43 	{
    51 	{
    44 	LOGTEXT("GppSamplerImpl::GppSamplerImpl");
    52 	LOGTEXT("GppSamplerImpl::GppSamplerImpl");
       
    53 #ifndef __SMP__
    45 	iInterruptStack = (TUint*)IntStackPtr();
    54 	iInterruptStack = (TUint*)IntStackPtr();
    46 
    55 #endif
       
    56 	
    47 	LOGTEXT("GppSamplerImpl::GppSamplerImpl - attaching to properties");
    57 	LOGTEXT("GppSamplerImpl::GppSamplerImpl - attaching to properties");
    48 
    58 
    49 	TInt err = iIsaStartAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressStart);
    59 	TInt err(iIsaStartAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressStart));
    50 	if(err != KErrNone)
    60 	if(err != KErrNone)
    51 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressStart not available"); 
    61 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressStart not available"); 
    52 	err = iIsaEndAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressEnd);
    62 	err = iIsaEndAddr.Attach(KIsaPropertyCat, EIsaPropertyIsaTaskAddressEnd);
    53 	if(err != KErrNone)
    63 	if(err != KErrNone)
    54 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressEnd not available"); 
    64 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaTaskAddressEnd not available"); 
    59 	if(err != KErrNone)
    69 	if(err != KErrNone)
    60 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaOsTaskRunningAddress not available"); 
    70 		LOGTEXT("GppSamplerImpl::GppSamplerImpl() - Property EIsaPropertyIsaOsTaskRunningAddress not available"); 
    61 	
    71 	
    62 	PROFILER_ISA_TASK_NAMES
    72 	PROFILER_ISA_TASK_NAMES
    63 	
    73 	
       
    74 	NKern::LockSystem();
       
    75 	// get status of ISA plug-in
       
    76 	TPropertyStatus status;
       
    77     if(iIsaPluginStatus.GetStatus(status))
       
    78         {
       
    79         iIsaPluginStatus.Get(iIsaStatus);
       
    80         LOGSTRING2("GppSamplerImpl::Reset - ISA plug-in status %d", iIsaStatus);
       
    81         }
       
    82 	NKern::UnlockSystem();
    64 	Reset();
    83 	Reset();
    65 	}
    84 	}
    66 
    85 
    67 DGppSamplerImpl::~DGppSamplerImpl() 
    86 DGppSamplerImpl::~DGppSamplerImpl() 
    68 	{
    87 	{
    72 	iIsaOsTaskRunning.Close();
    91 	iIsaOsTaskRunning.Close();
    73 	}
    92 	}
    74 
    93 
    75 void DGppSamplerImpl::Reset()
    94 void DGppSamplerImpl::Reset()
    76 	{
    95 	{
    77 	LOGTEXT("GppSamplerImpl::Reset");
    96     LOGSTRING("GppSamplerImpl::Reset() - entry");
    78 	iLastPc = 0;
    97 	iLastPc = 0;
    79 	iLastThread = 0xfffffffe;
    98 	iLastThread = 0xfffffffe;
    80 	iRepeat = 0;
    99 	iRepeat = 0;
    81 	iIsaStatus = 0;
   100 	iIsaStatus = 0;
    82 	iIsaStart = 0;
   101 	iIsaStart = 0;
    83 	iIsaEnd = 0;
   102 	iIsaEnd = 0;
    84 //	isaOsTaskRunningAddr = 0;
   103 //	isaOsTaskRunningAddr = 0;
       
   104 	iPrevTS = NKern::TickCount(); // get the system tick value for sync purposes 
    85 	
   105 	
    86 	// in SMP start time common with all CPUs, provided by DGeneralsDriver class
   106 	// in SMP start time common with all CPUs, provided by DGeneralsDriver class
    87 #ifndef __SMP__
   107 #ifndef __SMP__
    88 	iStartTime = ( NKern::TickCount() & 0xfffffffc );
   108 	iStartTime = ( iPrevTS & 0xfffffffc );
    89 #endif
   109 #else
    90 	
   110 	iStartTime = ( iPrevTS & 0xfffffff0 );
    91 	TPropertyStatus status;
   111 #endif
    92 	TInt osAddr = 0;
   112 	
    93 	
   113 	TInt osAddr(0);
    94 	LOGTEXT("GppSamplerImpl::Reset - getting status");
   114 	
    95 	
   115 	LOGSTRING("GppSamplerImpl::Reset - getting status");
    96 	// get status of ISA plug-in
       
    97 	if(iIsaPluginStatus.GetStatus(status))
       
    98 		{
       
    99 		iIsaPluginStatus.Get(iIsaStatus);
       
   100 		LOGSTRING2("GppSamplerImpl::Reset - ISA plug-in status %d", iIsaStatus);
       
   101 		}
       
   102 	
   116 	
   103 	if(iIsaStatus > 0)
   117 	if(iIsaStatus > 0)
   104 		{
   118 		{
   105 		LOGTEXT("GppSamplerImpl::Reset - get isa start address");
   119 		LOGSTRING("GppSamplerImpl::Reset - get isa start address");
   106 		iIsaStartAddr.Get(iIsaStart);
   120 		iIsaStartAddr.Get(iIsaStart);
   107 		LOGTEXT("GppSamplerImpl::Reset - get isa end address");
   121 		LOGSTRING("GppSamplerImpl::Reset - get isa end address");
   108 		iIsaEndAddr.Get(iIsaEnd);
   122 		iIsaEndAddr.Get(iIsaEnd);
   109 		LOGTEXT("GppSamplerImpl::Reset - get isa os_task_running address");
   123 		LOGSTRING("GppSamplerImpl::Reset - get isa os_task_running address");
   110 		iIsaOsTaskRunning.Get(osAddr);
   124 		iIsaOsTaskRunning.Get(osAddr);
   111 		isaOsTaskRunningAddr = reinterpret_cast<TInt*>(osAddr);
   125 		isaOsTaskRunningAddr = reinterpret_cast<TInt*>(osAddr);
   112 		LOGSTRING2("GppSamplerImpl::Reset - got isa os_task_running address 0x%X", osAddr);
   126 		LOGSTRING2("GppSamplerImpl::Reset - got isa os_task_running address 0x%X", osAddr);
   113 		}
   127 		}
   114 	
   128 	
   115 	LOGTEXT("GppSamplerImpl::Reset - initializing isa task list");
   129 	LOGSTRING("GppSamplerImpl::Reset - initializing isa task list");
   116 
   130 
   117 	iIsaSample = false;
   131 	iIsaSample = false;
   118 	
   132 	
   119 	for(TInt i=0;i<256;i++)
   133 	for(TInt i(0);i<256;i++)
   120 		knownIsaTasks[i] = -1;
   134 		knownIsaTasks[i] = -1;
   121 	
   135 	
   122 	knownIsaTaskCount = 0;
   136 	knownIsaTaskCount = 0;
   123     
   137     
   124 	iCpuSelector = 0x3;
   138 	iCpuSelector = 0x3;
   140         case 3:
   154         case 3:
   141             iCpuSelector = 0x8;
   155             iCpuSelector = 0x8;
   142             break;
   156             break;
   143         }
   157         }
   144 #endif
   158 #endif
       
   159     LOGSTRING("GppSamplerImpl::Reset() - exit");
   145 	}
   160 	}
   146 
   161 
   147 TUint8* DGppSamplerImpl::EncodeTag(TUint8* aPtr)
   162 TUint8* DGppSamplerImpl::EncodeTag(TUint8* aPtr)
   148 //
   163 //
   149 // Encode a tag and version to the trace data. This allows the offline analyser to 
   164 // Encode a tag and version to the trace data. This allows the offline analyser to 
   176 TUint8* DGppSamplerImpl::EncodeInt(TUint8* aPtr,TInt aValue)
   191 TUint8* DGppSamplerImpl::EncodeInt(TUint8* aPtr,TInt aValue)
   177 {
   192 {
   178 	LOGSTRING2("Encoding int 0x%x",aPtr);
   193 	LOGSTRING2("Encoding int 0x%x",aPtr);
   179 
   194 
   180 	LOGSTRING2("TIint = 0x%x",aValue);
   195 	LOGSTRING2("TIint = 0x%x",aValue);
   181 
   196 #ifdef __SMP__
       
   197 	TInt intState(0);
       
   198 	intState = __SPIN_LOCK_IRQSAVE(CpuSpinLock);
       
   199 #endif
   182 	TUint byte;
   200 	TUint byte;
   183 	for (;;)
   201 	for (;;)
   184 		{
   202 		{
   185 		byte = aValue & 0x7f;
   203 		byte = aValue & 0x7f;
   186 		if ((aValue >> 6) == (aValue >> 7))
   204 		if ((aValue >> 6) == (aValue >> 7))
   187 			break;
   205 			break;
   188 		aValue >>= 7;
   206 		aValue >>= 7;
   189 		*aPtr++ = byte;
   207 		*aPtr++ = byte;
   190 		}
   208 		}
   191 	*aPtr++ = byte | 0x80;
   209 	*aPtr++ = byte | 0x80;
   192 
   210 #ifdef __SMP__
       
   211 	__SPIN_UNLOCK_IRQRESTORE(CpuSpinLock, intState);
       
   212 #endif
   193 	LOGSTRING2("Encoded int 0x%x",aPtr);
   213 	LOGSTRING2("Encoded int 0x%x",aPtr);
   194 
   214 
   195 	return aPtr;
   215 	return aPtr;
   196 }
   216 }
   197 
   217 
   199 {
   219 {
   200 	LOGSTRING2("Encoding Uint 0x%x",aPtr);
   220 	LOGSTRING2("Encoding Uint 0x%x",aPtr);
   201 
   221 
   202 	LOGSTRING2("TUint = 0x%x",aValue);
   222 	LOGSTRING2("TUint = 0x%x",aValue);
   203 
   223 
   204 
   224 #ifdef __SMP__
       
   225 	TInt intState(0);
       
   226 	intState = __SPIN_LOCK_IRQSAVE(CpuSpinLock);
       
   227 #endif
   205 	TUint byte;
   228 	TUint byte;
   206 	for (;;)
   229 	for (;;)
   207 		{
   230 		{
   208 		byte = aValue & 0x7f;
   231 		byte = aValue & 0x7f;
   209 		aValue >>= 7;
   232 		aValue >>= 7;
   210 		if (aValue == 0)
   233 		if (aValue == 0)
   211 			break;
   234 			break;
   212 		*aPtr++ = byte;
   235 		*aPtr++ = byte;
   213 		}
   236 		}
   214 	*aPtr++ = byte | 0x80;
   237 	*aPtr++ = byte | 0x80;
   215 
   238 #ifdef __SMP__
       
   239 	__SPIN_UNLOCK_IRQRESTORE(CpuSpinLock, intState);
       
   240 #endif
   216 	LOGSTRING2("Encoded Uint 0x%x",aPtr);
   241 	LOGSTRING2("Encoded Uint 0x%x",aPtr);
   217 
   242 
   218 	return aPtr;
   243 	return aPtr;
   219 }
   244 }
   220 
   245 
   224 // This is currently limited to a descriptor that is up to 255 characters in length,
   249 // This is currently limited to a descriptor that is up to 255 characters in length,
   225 // and Unicode characters are truncated to 8 bits
   250 // and Unicode characters are truncated to 8 bits
   226 //
   251 //
   227 {
   252 {
   228 	LOGSTRING2("Encoding text 0x%x",aPtr);
   253 	LOGSTRING2("Encoding text 0x%x",aPtr);
   229 	TInt len=aDes.Length();
   254 	TInt len(aDes.Length());
       
   255 #ifdef __SMP__
       
   256 	TInt intState(0);
       
   257 	intState = __SPIN_LOCK_IRQSAVE(CpuSpinLock);
       
   258 #endif
   230 	*aPtr++ = TUint8(len);
   259 	*aPtr++ = TUint8(len);
   231 	const TText* p = aDes.Ptr();
   260 	const TText* p = aDes.Ptr();
   232 	while (--len >= 0)
   261 	while (--len >= 0)
   233 		{
   262 		{
   234 		*aPtr++ = TUint8(*p++);
   263 		*aPtr++ = TUint8(*p++);
   235 		}
   264 		}
   236 
   265 #ifdef __SMP__
       
   266 	__SPIN_UNLOCK_IRQRESTORE(CpuSpinLock, intState);
       
   267 #endif
   237 	LOGSTRING2("Encoded text 0x%x",aPtr);
   268 	LOGSTRING2("Encoded text 0x%x",aPtr);
   238 	return aPtr;
   269 	return aPtr;
   239 }
   270 }
   240 
   271 
   241 
   272 
   245 //
   276 //
   246 {
   277 {
   247 	LOGSTRING2("Encoding name 0x%x",aPtr);
   278 	LOGSTRING2("Encoding name 0x%x",aPtr);
   248 	TBuf8<0x5f> name;
   279 	TBuf8<0x5f> name;
   249 	aObject.TraceAppendName(name,false);
   280 	aObject.TraceAppendName(name,false);
   250 
   281 	LOGSTRING2("DGppSamplerImpl::EncodeName() - new process/thread found: %S", &name);
       
   282 	
   251 	if(id != 0xffffffff)
   283 	if(id != 0xffffffff)
   252 	{
   284 	{
   253 		name.Append('[');
   285 		name.Append('[');
   254 		name.AppendNum(id,EHex);
   286 		name.AppendNum(id,EHex);
   255 		name.Append(']');
   287 		name.Append(']');
   274 // also encoded.
   306 // also encoded.
   275 //
   307 //
   276 {
   308 {
   277 	LOGSTRING2("Encoding thread 0x%x",aPtr);	
   309 	LOGSTRING2("Encoding thread 0x%x",aPtr);	
   278 
   310 
   279 	DProcess& p = *aThread.iOwningProcess;
   311 	DProcess& p(*aThread.iOwningProcess);
   280 	
   312 	
   281 	aPtr = EncodeUint(aPtr, p.iId);
   313 	aPtr = EncodeUint(aPtr, p.iId);
   282 
   314 
   283 #ifdef __SMP__
   315 #ifdef __SMP__
   284     // check if first time founding
   316     // check if first time founding
   295         {
   327         {
   296         TAG(p) = (TAG(p) | iCpuSelector);
   328         TAG(p) = (TAG(p) | iCpuSelector);
   297         // The thread is 'unknown' to this sample, so encode the thread name
   329         // The thread is 'unknown' to this sample, so encode the thread name
   298         aPtr = EncodeName(aPtr, p, p.iId);     
   330         aPtr = EncodeName(aPtr, p, p.iId);     
   299         }
   331         }
       
   332     else
       
   333         {
       
   334         
       
   335         }
   300 #else
   336 #else
   301 	if (TAG(p) != iStartTime)
   337 	if (TAG(p) != iStartTime)
   302 	    {
   338 	    {
   303 		TAG(p) = iStartTime;
   339 		TAG(p) = iStartTime;
   304 		// Provide the name matching this process ID
   340 		// Provide the name matching this process ID
   331 TInt DGppSamplerImpl::CreateFirstSample()
   367 TInt DGppSamplerImpl::CreateFirstSample()
   332 {
   368 {
   333 	LOGTEXT("GppSamplerImpl::CreateFirstSample");
   369 	LOGTEXT("GppSamplerImpl::CreateFirstSample");
   334 	Reset();
   370 	Reset();
   335 
   371 
   336 	TUint8* w = this->tempBuf;
   372 	TUint8* w(this->tempBuf);
   337 	w = EncodeTag(w);
   373 	w = EncodeTag(w);
   338 
   374 
   339 	TInt length = w-tempBuf;
   375 	TInt length(w-tempBuf);
   340 
   376 
   341 	LOGSTRING2("TAG encoded, length %d",length);
   377 	LOGSTRING2("TAG encoded, length %d",length);
   342 	return length;
   378 	return length;
   343 }
   379 }
   344 
   380 
   345 TBool DGppSamplerImpl::IsaTaskKnown(TUint8 task)
   381 TBool DGppSamplerImpl::IsaTaskKnown(TUint8 task)
   346 {
   382 {
   347 	for(TInt i=0;i<256;i++)
   383 	for(TInt i(0);i<256;i++)
   348 	{
   384 	{
   349 		if(knownIsaTasks[i] == -1)
   385 		if(knownIsaTasks[i] == -1)
   350 		{
   386 		{
   351 			knownIsaTasks[i] = task;
   387 			knownIsaTasks[i] = task;
   352 			knownIsaTaskCount++;
   388 			knownIsaTaskCount++;
   384 // and Unicode characters are truncated to 8 bits
   420 // and Unicode characters are truncated to 8 bits
   385 //
   421 //
   386 {
   422 {
   387 	TBuf8<256> aDes;
   423 	TBuf8<256> aDes;
   388 	
   424 	
   389 //	#ifdef NCP_COMMON_PROFILER_ISA_TASKS 
       
   390 	if(iIsaStatus > 0)
   425 	if(iIsaStatus > 0)
   391 		{
   426 		{
   392 		// resolve the isa task name from the task name array
   427 		// resolve the isa task name from the task name array
   393 		if((task-100000) < PROFILER_ISA_OS_TASK_AMOUNT && process == false)
   428 		if((task-100000) < PROFILER_ISA_OS_TASK_AMOUNT && process == false)
   394 			{
   429 			{
   407 	aDes.Append('[');
   442 	aDes.Append('[');
   408 	aDes.AppendNum((task-100000),EHex);
   443 	aDes.AppendNum((task-100000),EHex);
   409 	aDes.Append(']');
   444 	aDes.Append(']');
   410 
   445 
   411 	LOGSTRING2("Encoding ISA name 0x%x",aPtr);
   446 	LOGSTRING2("Encoding ISA name 0x%x",aPtr);
   412 	TInt len=aDes.Length();
   447 	TInt len(aDes.Length());
   413 	*aPtr++ = TUint8(len);
   448 	*aPtr++ = TUint8(len);
   414 	const TText* p = aDes.Ptr();
   449 	const TText* p(aDes.Ptr());
   415 	while (--len >= 0)
   450 	while (--len >= 0)
   416 		{
   451 		{
   417 		*aPtr++ = TUint8(*p++);
   452 		*aPtr++ = TUint8(*p++);
   418 		}
   453 		}
   419 
   454 
   428 // This extracts the thread and PC that was current when the interrupt went off and
   463 // This extracts the thread and PC that was current when the interrupt went off and
   429 // encodes it into the sample data buffer. If enough data has been generated, the
   464 // encodes it into the sample data buffer. If enough data has been generated, the
   430 // DFC is triggered to complete a read request
   465 // DFC is triggered to complete a read request
   431 //
   466 //
   432     {
   467     {
   433 	TUint8* w(this->tempBuf);
   468     NThread* pN(NKern::CurrentThread());
   434 	
   469     TUint8* w(this->tempBuf);
   435 //    Kern::Printf(("Got thread 0x%08x"), &t);
   470     //TInt currCpu(NKern::CurrentCpu());
   436 #ifdef __SMP__
   471     TInt mySampleStartTime(NKern::TickCount()); // get the system tick value for sync purposes, in ms
   437     // get the program counter of irq mode
   472 //    TInt tickdiff(mySampleStartTime-iPrevTS);
   438     TUint32 pc = (TUint32)Arm::IrqReturnAddress();
   473     
       
   474     if (Kern::NThreadToDThread(pN)==NULL)
       
   475         {
       
   476         LOGSTRING("Kern::NThreadToDThread is null");
       
   477         }
       
   478 
       
   479     else
       
   480         {
       
   481         // check timestamp & compare to previous
       
   482         // if out of sync, encode unknown::unknown thread
       
   483 
       
   484 /*
       
   485 // In SMP environment there have been missing ticks. These prints are for helping debug this issue
       
   486 // but solution might not work.
       
   487         if(tickdiff > 1)
       
   488             {
       
   489             Kern::Printf(("DGppSamplerImpl::SampleImpl() - Current time tick %d"), mySampleStartTime);
       
   490             Kern::Printf(("DGppSamplerImpl::SampleImpl() - Previous time tick %d"), iPrevTS);
       
   491 //            Kern::Printf(("DGppSamplerImpl::SampleImpl() - Tick period %d"),NKern::TickPeriod());
       
   492             Kern::Printf(("DGppSamplerImpl::SampleImpl() - Tick difference %d"),tickdiff);
       
   493             Kern::Printf(("DGppSamplerImpl::SampleImpl() - Current cpu %d"),NKern::CurrentCpu());
       
   494             }
       
   495 //        else
       
   496 //            {
       
   497 //            Kern::Printf(("DGppSamplerImpl::SampleImpl() - Tick differance <= 1: %d"),tickdiff);
       
   498 //            }
       
   499 */
       
   500 
       
   501         TLinAddr pC;
       
   502             
       
   503 #ifdef __SMP__
       
   504         pC = Arm::IrqReturnAddress();
   439 #else
   505 #else
   440     // get program counter of irq mode
   506         // get program counter of irq mode
   441     TUint32 pc = iInterruptStack[-1];
   507         pC = iInterruptStack[-1]; // ignore the low bit being set for THUMB mode - we use for something else
   442 #endif
   508 #endif
   443     //LOGSTRING3("pc value 0x%x sp 0x%x",pc,iInterruptStack);
   509         //Kern::Printf(("pc value 0x%x sp 0x%x"),pc,iInterruptStack);
   444 
   510         pC &= ~1;
   445 	// ignore the low bit being set for THUMB mode - we use for something else
   511         TInt diff(pC - iLastPc);
   446 	pc &= ~1;			
   512         iLastPc = pC;
   447 	TInt diff = pc - iLastPc;
   513            
   448 	iLastPc = pc;
   514         if(iIsaStatus > 0)
   449 
   515             {
   450 	if(iIsaStatus > 0)
   516             if((TUint32)pC > (TUint32)iIsaStart && (TUint32)pC < (TUint32)iIsaEnd)
   451 		{
   517                 {
   452 		if((TUint32)pc > (TUint32)iIsaStart && (TUint32)pc < (TUint32)iIsaEnd)
   518                 iIsaSample = true;
   453 			{
   519                 }
   454 			LOGSTRING2("Identified ISA execution at 0x%x",pc);
   520             else
   455 			iIsaSample = true;
   521                 {
   456 			}
   522                 iIsaSample = false;
   457 		else
   523                 }
   458 			{
   524             }
   459 			LOGSTRING2("Normal sample at 0x%x",pc);
   525         
   460 			iIsaSample = false;
   526 //        if((TUint32)pC < 0x80000000 || (TUint32)pC > 0x8FFFFFFF)
   461 			}
   527 //            {
   462 		}
   528 //            //Kern::Printf("DGppSamplerImpl::SampleImpl() - wrong PC value, 0x%x", (TUint32)pC);
   463 
   529 //            iIsaSample = true;
   464 	// request for current thread from kernel
   530 //            }
   465 	DThread& t = ((DThread&)*Kern::NThreadToDThread(NKern::CurrentThread()));
   531         
   466 	
   532         // request for current thread from kernel
   467 	TUint tid;
   533         DThread& t(((DThread&)*Kern::NThreadToDThread(pN)));
   468 	TUint8 isaTask = 0;
   534     
   469 	if(iIsaSample)
   535         TUint tid;
   470 	{
   536         TUint8 isaTask(0);
   471 		LOGSTRING2("Reading ISA task number from 0x%x",isaOsTaskRunningAddr);
   537         if(iIsaSample)
   472 
   538             {
   473 		// if we don't get reasonable ISA address to read, skip ISA task handling
   539             //Kern::Printf(("Reading ISA task number from 0x%x"),isaOsTaskRunningAddr);
   474 		if(isaOsTaskRunningAddr == 0)
   540             // if we don't get reasonable ISA address to read, skip ISA task handling
   475 			{
   541             if(isaOsTaskRunningAddr == 0)
   476 			tid = 100000; // to tell the difference from SOS threads
   542                 {
   477 			iIsaSample = false;
   543                 tid = 100000; // to tell the difference from SOS threads
   478 			}
   544                 iIsaSample = false;
   479 		else	// normal ISA task parsing process
   545                 }
   480 			{
   546             else    // normal ISA task parsing process
   481 			isaTask = *isaOsTaskRunningAddr;
   547                 {
   482 			LOGSTRING2("ISA task = %d",isaTask);
   548                 isaTask = *isaOsTaskRunningAddr;
   483 			tid = isaTask;
   549                 LOGSTRING2("ISA task = %d",isaTask);
   484 			// this will make sure we don't mix ISA tasks and normal tasks
   550                 tid = isaTask;
   485 			tid += 100000;
   551                 // this will make sure we don't mix ISA tasks and normal tasks
   486 			}
   552                 tid += 100000;
   487 
   553                 }
   488 	}
   554             }
   489 	else
   555         else
   490 	{
   556             {
   491 		tid = t.iId;
   557             tid = t.iId;
   492 	}
   558             }
   493 
   559     
   494 	if (tid != iLastThread)
   560         if (tid != iLastThread)
   495 	{
   561             {
   496 		// Change of thread is marked in the low bit of the PC difference
   562             diff |= 1;    // Change of thread is marked in the low bit of the PC difference
   497 		diff |= 1;
   563             }
   498 	}
   564         TUint rp(iRepeat);
   499 	TUint rp = iRepeat;
   565         if (diff == 0)
   500 	if (diff == 0)
   566             {
   501 	{
   567             iRepeat = rp + 1; // Identical sample, bump up the repeat count
   502 		// Identical sample, bump up the repeat count
   568             }
   503 		iRepeat = rp + 1;
   569         else
   504 	}
   570             {
   505 	else
   571             if (rp)
   506 	{
   572                 {
   507 		if (rp)
   573                 w = EncodeRepeat(w); // Encode the repeat data
   508 		{
   574                 }
   509 			// Encode the repeat data
   575             w = EncodeInt(w, diff);   // Encode the PC difference
   510 			w = EncodeRepeat(w);
   576             //if (diff & 0x1 == 1)
   511 		}
   577             if (diff & 1)
   512 		// Encode the PC difference
   578                 {
   513 		w = EncodeInt(w, diff);
   579 //                LOGSTRING3("Encode pc diff curr cpu %d diff %d", currCpu, diff);
   514 		if (diff & 1)
   580                 if(iIsaSample)   // Encode the new thread ID
   515 		{
   581                     {
   516 			// Encode the new thread ID
   582                     iLastThread = tid;
   517 			if(iIsaSample)
   583 //                    LOGSTRING2("Encode thread id UINT curr cpu %d", currCpu);
   518 			{
   584                     w = EncodeUint(w,tid);
   519 				iLastThread = tid;
   585                     if(!this->IsaTaskKnown(isaTask))
   520 				w = EncodeUint(w,tid);
   586                         {
   521 
   587                         //Kern::Printf("Encode isa task");
   522 				if(!this->IsaTaskKnown(isaTask))
   588                         w = EncodeIsaTask(w,iLastThread);
   523 				{
   589                         }
   524 					w = EncodeIsaTask(w,iLastThread);
   590                     //LOGSTRING2("Sample total length: %d",w-tempBuf);
   525 				}
   591                     TInt length = w-tempBuf;
   526 				//LOGSTRING2("Sample total length: %d",w-tempBuf);
   592                     return length;  // encoded isa task, return here
   527 				TInt length = w-tempBuf;
   593                     }
   528 				// encoded isa task, return here
   594                 iLastThread = tid;
   529 				return length;
   595 //                LOGSTRING2("Encode lastthread id UinT curr cpu %d", currCpu);
   530 			}
   596                 w = EncodeUint(w, tid);
   531 		
   597     
   532 			iLastThread = tid;
   598 #ifdef __SMP__
   533 			w = EncodeUint(w, tid);
   599                 // iStartTime format: 0xXXXXXXX0, the last byte set to zero
   534 
   600                 // iMask =  0xfffffff0(0b111....1110000), last bits reserved for the CPUs bit0=CPU0 etc.
   535 #ifdef __SMP__
   601                 // iCpuSelector = 0x1(0b0001), 0x2(0b0010), 0x4(0b0100) or 0x8(0b1000), to use against the mask
   536 			// iStartTime format: 0xXXXXXXX0, the last byte set to zero
   602                 //#define  TAG(obj)    (*(TUint32*)&(obj.iAsyncDeleteNext))
   537 			// iMask =  0xfffffff0(0b111....1110000)
   603                 // check first time founding
   538 			// iCpuSelector = 0x1(0b0001), 0x2(0b0010), 0x4(0b0100) or 0x8(0b1000) 
   604                 LOGSTRING4("TAG(t) 0x%x, iMask 0x%x, AND 0x%x ",TAG(t),iMask, (TAG(t)& iMask));
   539 			
   605                 if ((TAG(t) & iMask) != iStartTime)
   540 			// check first time founding
   606                     {
   541 			if ((TAG(t) & iMask) != iStartTime)
   607                     // mark tagged for this CPU
   542 			    {
   608                     TAG(t) = (iStartTime | iCpuSelector);
   543 			    // mark tagged for this CPU
   609                     
   544 				TAG(t) = (iStartTime | iCpuSelector);
   610                     // The thread is 'unknown' to this sample, so encode the thread name
   545 				
   611 //                    LOGSTRING2("Encode SMP thread start time curr cpu %d", currCpu);
   546 				// The thread is 'unknown' to this sample, so encode the thread name
   612                     w = EncodeThread(w, t);
   547 				w = EncodeThread(w, t);		
   613                     }
   548 			    }
   614                 // check if thread appeared on this CPU
   549 			// check if thread appeared on this CPU
   615                 else if((TAG(t) & iCpuSelector) != iCpuSelector)
   550 			else if((TAG(t) & iCpuSelector) != iCpuSelector)
   616                     {
   551 			    {
   617                     TAG(t) = (TAG(t) | iCpuSelector);
   552                 TAG(t) = (TAG(t) | iCpuSelector);
   618                     // The thread is 'unknown' to this sample, so encode the thread name
   553                 // The thread is 'unknown' to this sample, so encode the thread name
   619 //                    LOGSTRING2("Encode SMP thread cpu selector curr cpu %d", currCpu);
   554                 w = EncodeThread(w, t);     
   620                     w = EncodeThread(w, t);
   555 			    }
   621                     }
   556 #else
   622 #else
   557 			// check if tag has not been set, neither original nor 
   623                 // check if tag has not been set, neither original nor 
   558             if ((TAG(t) & 0xfffffffc) != iStartTime)
   624                 if ((TAG(t) & 0xfffffffc) != iStartTime)
   559                 {
   625                     {
   560                 TAG(t) = ((TAG(t) & 0x3) | iStartTime);
   626                     TAG(t) = ((TAG(t) & 0x3) | iStartTime);
   561                 // The thread is 'unknown' to this sample, so encode the thread name
   627                     // The thread is 'unknown' to this sample, so encode the thread name
   562                 w = EncodeThread(w, t);     
   628                     w = EncodeThread(w, t);
       
   629                     }
       
   630         
       
   631 #endif
   563                 }
   632                 }
   564 #endif
   633             }
   565 		    }
   634         }
   566 	    }
   635 
   567 	LOGSTRING2("Sample total length: %d",w-tempBuf);
   636     TInt length(w-tempBuf);
   568 	TInt length = w-tempBuf;
   637     LOGSTRING2("Sample total length: %d",length);
   569 
   638     iPrevTS = mySampleStartTime;  // get the system tick value for sync purposes 
   570 	return length;
   639     return length;
   571 }
   640     }
   572 
   641