perfsrv/piprofiler/plugins/GeneralsPlugin/src/GeneralsDriver.cpp
changeset 51 98307c651589
parent 20 a71a3e32a2ae
child 62 1c2bb2fc7c87
equal deleted inserted replaced
42:0ff24a8f6ca2 51:98307c651589
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //
       
    20 // LDD for thread time profiling
       
    21 //
       
    22 
       
    23 #include <kern_priv.h>
       
    24 #include <platform.h>
       
    25 #include <arm.h>
       
    26 
       
    27 #ifdef __SMP__
       
    28 #include <assp/naviengine/naviengine.h> 
       
    29 #include <nkernsmp/arm/arm_gic.h>
       
    30 #include <nkernsmp/arm/arm_tmr.h>
       
    31 #endif
       
    32 
       
    33 #include "GeneralsDriver.h"
       
    34 #include <piprofiler/PluginDriver.h>
       
    35 #include <piprofiler/PluginSampler.h>
       
    36 #include <piprofiler/ProfilerTraces.h>
       
    37 
       
    38 #include "GppSamplerImpl.h"
       
    39 #include "GfcSamplerImpl.h"
       
    40 #include "IttSamplerImpl.h"
       
    41 #include "MemSamplerImpl.h"
       
    42 #include "PriSamplerImpl.h"
       
    43 
       
    44 
       
    45 #ifndef __SMP__
       
    46 extern TUint* IntStackPtr();
       
    47 extern void UsrModLr(TUint32*);
       
    48 #endif
       
    49 // for security check
       
    50 #define KProfilerExeSecurUid 0x2001E5AD
       
    51 static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
       
    52 static _LIT_SECURITY_POLICY_FAIL( KDenyAllPolicy );
       
    53 
       
    54 #define SEPARATE_DFC_QUEUE
       
    55 // CONSTANTS
       
    56 
       
    57 //_LIT(DProfilerThread,"DProfilerThread");
       
    58 //const TInt KDProfilerThreadPriority = 27;
       
    59 
       
    60 #ifdef SEPARATE_DFC_QUEUE
       
    61 const TInt KGeneralsDriverThreadPriority = 24;
       
    62 _LIT(KGeneralsDriverThread, "PIGeneralsDriver");
       
    63 
       
    64 #endif
       
    65 
       
    66 // global Dfc Que
       
    67 //TDynamicDfcQue* gDfcQ;
       
    68 
       
    69 //#ifdef __SMP__
       
    70 //
       
    71 //enum  TNaviEngineAsspInterruptIdExtension
       
    72 //{
       
    73 //    KIntProfilerBase = 99      //  Sampling profiler interrupt base. 
       
    74 //    //  Each CPU is assigned a sampling interrupt from this base
       
    75 //    //  CPU-0's sampling interrupt is KIntIdSamplingBase + 0
       
    76 //    //  CPU-n's sampling interrupt is KIntIdSamplingBase + n
       
    77 //};
       
    78 //#endif
       
    79 
       
    80 /*
       
    81  *
       
    82  *
       
    83  *	Class DGfcProfilerFactory definition
       
    84  *
       
    85  *
       
    86  */
       
    87 
       
    88 class DGeneralsProfilerFactory : public DLogicalDevice
       
    89 {
       
    90 	public:
       
    91 		DGeneralsProfilerFactory();
       
    92 		~DGeneralsProfilerFactory();
       
    93 
       
    94 	public:
       
    95 		virtual TInt Install();
       
    96 		virtual void GetCaps(TDes8& aDes) const;
       
    97 		virtual TInt Create(DLogicalChannelBase*& aChannel);
       
    98 };
       
    99 
       
   100 /*
       
   101  *
       
   102  *
       
   103  *	Class DGfcDriver definition
       
   104  *
       
   105  *
       
   106  */
       
   107 class DPluginDriver;
       
   108 
       
   109 class DGeneralsDriver : public DPluginDriver
       
   110 {
       
   111 
       
   112 public:
       
   113 	DGeneralsDriver();
       
   114 	~DGeneralsDriver();
       
   115 
       
   116 private:
       
   117 	TInt					NewStart(TInt aRate);
       
   118 	static void				NewDoProfilerProfile(TAny*);
       
   119 	static void				NewDoDfc(TAny*);
       
   120 	
       
   121 	// called by each core
       
   122 	static void				Sample(TAny*);
       
   123 
       
   124 	TInt					GetSampleTime(TUint32* time);
       
   125 	//TInt					Test(TUint32 testCase); 
       
   126 
       
   127 	TInt					StartSampling();
       
   128 	TInt                    StopSampling();
       
   129 
       
   130 	void					InitialiseSamplerList(); 
       
   131 
       
   132 	DProfilerSamplerBase*	GetSamplerForId(TInt samplerId);
       
   133 	TInt					GetSamplerVersion(TDes* aDes);
       
   134 	
       
   135 #ifdef __SMP__
       
   136 	void                    UnbindInterrupts();
       
   137 #endif
       
   138 	TInt					ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus);
       
   139 
       
   140 	TInt					MarkTraceActive(TInt samplerIdToActivate);
       
   141 	TInt					MarkTraceInactive(TInt samplerIdToDisable);
       
   142 	TInt					OutputSettingsForTrace(TInt samplerId,TInt settings);
       
   143 	TInt					AdditionalTraceSettings(TInt samplerId,TInt settings);
       
   144 	TInt					AdditionalTraceSettings2(TInt samplerId,TInt settings);
       
   145 	TInt					SetSamplingPeriod(TInt /*samplerId*/,TInt settings);
       
   146 private:
       
   147 	// create the driver in EKA-2 version
       
   148 	TInt			        DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
   149 
       
   150 	// receive commands and control in EKA-2 version
       
   151 	void					HandleMsg(TMessageBase* aMsg);
       
   152 private:
       
   153 	// timer mechanism in EKA-2 version
       
   154 	NTimer						iTimer;
       
   155 	TDfc						iNewDfc;
       
   156 	TInt						iCount;
       
   157 	TInt						iLastPcVal;					
       
   158 	TInt						iPeriod;
       
   159 	
       
   160 	// sync sample number property for synchronizing other samplers
       
   161 	RPropertyRef 				iSampleStartTimeProp;
       
   162 	TInt						iSampleStartTime;
       
   163 	
       
   164 	DProfilerGppSampler<10000> 	gppSampler;
       
   165 #ifdef __SMP__
       
   166 	DProfilerGppSampler<10000>  gppSampler2;
       
   167     DProfilerGppSampler<10000>  gppSampler3;
       
   168     DProfilerGppSampler<10000>  gppSampler4;
       
   169 #endif
       
   170 	DProfilerGfcSampler<10000> 	gfcSampler;
       
   171 	DProfilerIttSampler<10000> 	ittSampler;
       
   172 	DProfilerMemSampler<40000> 	memSampler;
       
   173 	DProfilerPriSampler<10000> 	priSampler;
       
   174 #ifdef __SMP__
       
   175 //    DProfilerPriSampler<10000>  priSampler2;
       
   176 //    DProfilerPriSampler<10000>  priSampler3;
       
   177 //    DProfilerPriSampler<10000>  priSampler4;
       
   178 #endif
       
   179 	
       
   180 #ifndef __SMP__
       
   181 	static const TInt			KSamplerAmount = 5;
       
   182 #else
       
   183     static const TInt           KSamplerAmount = 8;
       
   184 #endif
       
   185 	DProfilerSamplerBase*		iSamplers[KSamplerAmount];
       
   186     TInt                        iMaxCpus;
       
   187     TUint32                     iStartTime; 
       
   188 	
       
   189 #ifdef SEPARATE_DFC_QUEUE
       
   190 	TDynamicDfcQue*             iDfcQ;
       
   191 #endif
       
   192 };
       
   193 
       
   194 /*
       
   195  *
       
   196  *
       
   197  *	Class DGeneralsProfilerFactory implementation
       
   198  *
       
   199  *
       
   200  */
       
   201 
       
   202 DECLARE_STANDARD_LDD()
       
   203     {
       
   204 	return new DGeneralsProfilerFactory();
       
   205     }
       
   206 
       
   207 TInt DGeneralsProfilerFactory::Create(DLogicalChannelBase*& aChannel)
       
   208     {
       
   209 	aChannel = new DGeneralsDriver;
       
   210 	return aChannel?KErrNone:KErrNoMemory;
       
   211     }
       
   212 
       
   213 
       
   214 DGeneralsProfilerFactory::DGeneralsProfilerFactory()
       
   215     {
       
   216 	// major, minor, and build version number
       
   217     iVersion=TVersion(1,0,1);
       
   218     }
       
   219 
       
   220 DGeneralsProfilerFactory::~DGeneralsProfilerFactory()
       
   221     {
       
   222 //    if (gDfcQ)
       
   223 //        {
       
   224 //        gDfcQ->Destroy();
       
   225 //        }
       
   226     }
       
   227 
       
   228 TInt DGeneralsProfilerFactory::Install()
       
   229     {
       
   230     return(SetName(&KPluginSamplerName));
       
   231     }
       
   232 
       
   233 void DGeneralsProfilerFactory::GetCaps(TDes8& aDes) const
       
   234     {
       
   235     TCapsSamplerV01 b;
       
   236     
       
   237     b.iVersion=TVersion(1,0,1);
       
   238     
       
   239     aDes.FillZ(aDes.MaxLength());
       
   240     aDes.Copy((TUint8*)&b,Min(aDes.MaxLength(),sizeof(b)));
       
   241     }
       
   242 
       
   243 /*
       
   244  *
       
   245  *
       
   246  *	Class DGeneralsDriver implementation
       
   247  *
       
   248  *
       
   249  */
       
   250  
       
   251 DGeneralsDriver::DGeneralsDriver() :
       
   252 	iTimer(NewDoProfilerProfile,this),
       
   253 	iNewDfc(NewDoDfc,this,NULL,7),
       
   254 #ifdef __SMP__
       
   255 	gppSampler(0),
       
   256 	gppSampler2(1),
       
   257     gppSampler3(2),
       
   258     gppSampler4(3),
       
   259 #endif
       
   260 	gfcSampler(gppSampler.GetExportData()),
       
   261 	ittSampler(gppSampler.GetExportData()),
       
   262 	memSampler(gppSampler.GetExportData(), PROFILER_MEM_SAMPLER_ID),
       
   263 	priSampler(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
       
   264 #ifdef __SMP__
       
   265 //    ,priSampler2(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
       
   266 //    priSampler3(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID),
       
   267 //    priSampler4(gppSampler.GetExportData(), PROFILER_PRI_SAMPLER_ID)
       
   268 #endif
       
   269     {
       
   270 	LOGSTRING("DGeneralsDriver::DGeneralsDriver()");
       
   271 
       
   272 	iState = EStopped;
       
   273 	iEndRequestStatus = 0;
       
   274 	doingDfc = 0;
       
   275 	sampleRunning = 0;
       
   276 	iSyncOffset = 0;
       
   277 	iStartTime = 0;
       
   278 	InitialiseSamplerList();
       
   279     }
       
   280 
       
   281 /*
       
   282  *
       
   283  *	This method has to be changed for each new sampler
       
   284  *
       
   285  */ 
       
   286 void DGeneralsDriver::InitialiseSamplerList()
       
   287 	{
       
   288 	// initialize all samplers to zero
       
   289 	for(TInt i(0);i<KSamplerAmount;i++)
       
   290 		{
       
   291 		iSamplers[i] = 0;
       
   292 		}
       
   293 
       
   294 	TInt i(0);
       
   295 	iSamplers[i] = &gppSampler;i++;
       
   296 #ifdef __SMP__
       
   297 	iSamplers[i] = &gppSampler2;i++;
       
   298     iSamplers[i] = &gppSampler3;i++;
       
   299     iSamplers[i] = &gppSampler4;i++;
       
   300 #endif
       
   301 	iSamplers[i] = &gfcSampler;i++;
       
   302 	iSamplers[i] = &ittSampler;i++;
       
   303 	iSamplers[i] = &memSampler;i++;
       
   304 	iSamplers[i] = &priSampler;i++;
       
   305 	
       
   306 #ifdef __SMP__
       
   307     // get the number of cpus
       
   308     iMaxCpus = NKern::NumberOfCpus();
       
   309 #else
       
   310     iMaxCpus = 0;
       
   311 #endif
       
   312     
       
   313 	// initialize synchronizing property
       
   314 	LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - initializing property");
       
   315 	TInt r(iSampleStartTimeProp.Attach(KGppPropertyCat, EGppPropertySyncSampleNumber));
       
   316     if (r!=KErrNone)
       
   317         {
       
   318         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in attaching counter property, error %d", r);
       
   319         }
       
   320     LOGSTRING("DGeneralsDriver::InitialiseSamplerList() - defining properties");
       
   321     r = iSampleStartTimeProp.Define(RProperty::EInt, KAllowAllPolicy, KDenyAllPolicy, 0, NULL);
       
   322     if (r!=KErrNone)
       
   323         {
       
   324         LOGSTRING2("DGeneralsDriver::InitialiseSamplerList() - error in defining counter property, error %d", r);
       
   325         }	
       
   326 	}
       
   327 
       
   328 
       
   329 DProfilerSamplerBase* DGeneralsDriver::GetSamplerForId(TInt samplerIdToGet)
       
   330     {
       
   331 	for(TInt i(0);i<KSamplerAmount;i++)
       
   332 	    {
       
   333 		if(iSamplers[i]->iSamplerId == samplerIdToGet)
       
   334 		    {
       
   335 			return iSamplers[i];
       
   336 		    }
       
   337 	    }
       
   338 	return (DProfilerSamplerBase*)0;
       
   339     }
       
   340 
       
   341 TInt DGeneralsDriver::DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer)
       
   342     {
       
   343     TUint8 err(KErrNone);
       
   344     
       
   345     if (!Kern::QueryVersionSupported(TVersion(1,0,1),aVer))
       
   346 	   	return KErrNotSupported;
       
   347     
       
   348     // just for testing 
       
   349 #ifndef __SMP__
       
   350     LOGTEXT("Initializing the stack pointer");
       
   351     stackTop=(TUint32*)IntStackPtr();
       
   352     LOGSTRING2("Got stack pointer 0x%x",(TUint32)stackTop);
       
   353 #endif
       
   354 
       
   355     iClient = &Kern::CurrentThread();
       
   356     err = iClient->Open();
       
   357 	
       
   358     DProcess* clientProcess(iClient->iOwningProcess);
       
   359     if (clientProcess)
       
   360         {
       
   361         //Require Power Management and All Files to use this driver
       
   362         // Not ideal, but better than nothing
       
   363         if(!Kern::CurrentThreadHasCapability(ECapabilityPowerMgmt,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
       
   364             return KErrPermissionDenied;
       
   365         if(!Kern::CurrentThreadHasCapability(ECapabilityAllFiles,__PLATSEC_DIAGNOSTIC_STRING("Checked by GeneralsDriver.ldd")))
       
   366             return KErrPermissionDenied;  
       
   367         
       
   368         SSecurityInfo secureInfo = clientProcess->iS;
       
   369         if (secureInfo.iSecureId != KProfilerExeSecurUid)
       
   370             {
       
   371             return KErrPermissionDenied;
       
   372             }
       
   373         }
       
   374     
       
   375     // initiate sample stream ready for collecting the trace data
       
   376 	iSampleStream.InsertCurrentClient(iClient);
       
   377 	
       
   378 	iTimer.Cancel();
       
   379 	iNewDfc.Cancel();
       
   380 
       
   381 	Kern::SetThreadPriority(24);
       
   382 
       
   383 #ifdef SEPARATE_DFC_QUEUE
       
   384 	err = Kern::DynamicDfcQCreate(iDfcQ, KGeneralsDriverThreadPriority, TBuf8<32>( KGeneralsDriverThread ));
       
   385 	if (KErrNone == err)
       
   386         {
       
   387         SetDfcQ(iDfcQ);
       
   388         iNewDfc.SetDfcQ(iDfcQ);
       
   389         iMsgQ.Receive();
       
   390         return err;
       
   391         }
       
   392 #else
       
   393 	SetDfcQ(Kern::DfcQue0());
       
   394 	iNewDfc.SetDfcQ(iDfcQ);
       
   395 	iMsgQ.Receive();
       
   396 #endif
       
   397 	return err;
       
   398     }
       
   399 
       
   400 DGeneralsDriver::~DGeneralsDriver()
       
   401     {
       
   402 	if (iState!=EStopped)
       
   403 	    iTimer.Cancel();
       
   404 	iNewDfc.Cancel();
       
   405 	
       
   406 #ifdef SEPARATE_DFC_QUEUE
       
   407 	if(iDfcQ)
       
   408 	    iDfcQ->Destroy();
       
   409 #endif
       
   410 	
       
   411 	iSampleStartTimeProp.Close();
       
   412 	Kern::SafeClose((DObject*&)iClient,NULL);
       
   413     }
       
   414 
       
   415 
       
   416 TInt DGeneralsDriver::GetSampleTime(TUint32* time)
       
   417     {
       
   418 	LOGSTRING("DGeneralsDriver::GetSampleTime - entry");
       
   419 
       
   420 	Kern::ThreadRawWrite(	iClient,(TAny*)time, 
       
   421 							(TAny*)&gppSampler.GetExportData()->sampleNumber, 
       
   422 							4, iClient);
       
   423 
       
   424 	LOGSTRING("DGeneralsDriver::GetSampleTime - exit");
       
   425 
       
   426 	return KErrNone;
       
   427     }
       
   428 
       
   429 
       
   430 TInt DGeneralsDriver::GetSamplerVersion(TDes* aDes)
       
   431     {
       
   432 	LOGSTRING2("DGeneralsDriver::GetSamplerVersion - 0x%x",aDes);
       
   433 	
       
   434 	TBuf8<16> aBuf;
       
   435 	aBuf.Append(PROFILER_SAMPLER_VERSION);
       
   436 	Kern::ThreadDesWrite(iClient,aDes,aBuf,0,KChunkShiftBy0,iClient);
       
   437 	LOGSTRING("DGeneralsDriver::GetSamplerVersion - written client descriptor");
       
   438 	return KErrNone;
       
   439     }
       
   440 
       
   441 TInt DGeneralsDriver::NewStart(TInt aDelay)
       
   442     {	
       
   443 	LOGSTRING("DGeneralsDriver::NewStart");
       
   444 	iEndRequestStatus = 0;
       
   445 	
       
   446 	aDelay = Min(KMaxDelay, Max(KMinDelay, aDelay));
       
   447 
       
   448 	// always use this rate
       
   449 	iPeriod = aDelay;
       
   450 	
       
   451 #ifdef __SMP__
       
   452     /*
       
   453      * Bind and enable the sampling interupts associated with each core. 
       
   454      */
       
   455     TInt err(0);
       
   456     
       
   457     TUint32 flags = NKern::EIrqBind_Count;
       
   458 
       
   459 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
       
   460     err = NKern::InterruptBind( KIntProfilerBase - 32 , DGeneralsDriver::Sample, this, flags, 0);
       
   461     if(err < 0)
       
   462         Kern::Printf(" InterruptBind KIntProfilerBase - 32 ret = %d", err );
       
   463     
       
   464 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
       
   465     err = NKern::InterruptBind( KIntProfilerBase + 1 - 32 , DGeneralsDriver::Sample, this, flags, 0);
       
   466     if(err < 0)
       
   467         Kern::Printf(" InterruptBind KIntProfilerBase + 1 - 32 ret = %d", err );
       
   468 
       
   469 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
       
   470     err = NKern::InterruptBind(KIntProfilerBase + 2 - 32 , DGeneralsDriver::Sample, this, flags, 0);
       
   471     if(err < 0)
       
   472         Kern::Printf(" InterruptBind KIntProfilerBase + 2 - 32 ret = %d", err );
       
   473 
       
   474 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
       
   475     err = NKern::InterruptBind(KIntProfilerBase + 3 - 32 , DGeneralsDriver::Sample, this, flags, 0);
       
   476     if(err < 0)
       
   477         Kern::Printf(" InterruptBind KIntProfilerBase + 3 - 32 ret = %d", err );
       
   478 
       
   479 
       
   480     err = NKern::InterruptEnable(KIntProfilerBase - 32);
       
   481     if(err < 0)
       
   482         Kern::Printf(" InterruptEnable KIntProfilerBase - 32 ret = %d", err );
       
   483     
       
   484     err = NKern::InterruptEnable(KIntProfilerBase + 1 - 32);
       
   485     if(err < 0)
       
   486         Kern::Printf(" InterruptEnable KIntProfilerBase + 1 - 32 ret = %d", err );
       
   487 
       
   488     err = NKern::InterruptEnable(KIntProfilerBase + 2 - 32);
       
   489     if(err < 0)
       
   490         Kern::Printf(" InterruptEnable KIntProfilerBase + 2 - 32 ret = %d", err );
       
   491 
       
   492     err = NKern::InterruptEnable(KIntProfilerBase + 3 - 32);
       
   493     if(err < 0)
       
   494         Kern::Printf(" InterruptEnable KIntProfilerBase + 3 - 32 ret = %d", err );
       
   495         
       
   496 #endif
       
   497 	
       
   498 	iTimer.OneShot(aDelay);
       
   499 	
       
   500 	iState = ERunning;
       
   501 
       
   502 	return KErrNone;
       
   503     }
       
   504 
       
   505 /*
       
   506  *	This function is run in each interrupt
       
   507  */
       
   508 // EKA-2 implementation of the sampler method
       
   509 
       
   510 void DGeneralsDriver::NewDoProfilerProfile(TAny* aPtr)
       
   511     {
       
   512     LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - entry");
       
   513     
       
   514 #ifdef __SMP__      
       
   515     TInt currCpu(NKern::CurrentCpu());
       
   516 #endif
       
   517     TInt8 postSampleNeeded(0);
       
   518     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
       
   519 
       
   520 	if (d.iState == ERunning && d.sampleRunning == 0)
       
   521 	    {
       
   522         // start timer again
       
   523 		d.iTimer.Again(d.iPeriod);
       
   524 		d.sampleRunning++;
       
   525         
       
   526 #ifdef __SMP__      
       
   527         // print out the sample tick
       
   528         if(d.gppSampler.GetExportData()->sampleNumber% 1000 == 0) 
       
   529             {
       
   530             Kern::Printf(("PIPROF SAMPLE TICK, #%d"), d.gppSampler.GetExportData()->sampleNumber);
       
   531             }
       
   532         // call the actual CPU sampling function for CPU 0 (in NaviEngine), later may be on any of the CPUs
       
   533         Sample(aPtr);
       
   534         
       
   535         // post-sampling for NTimer interrupted CPU
       
   536         postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
       
   537         
       
   538         /* 
       
   539         This is the master sampler from the watchdog timer, so 
       
   540         send interrupts to the other CPUs
       
   541         */
       
   542         TScheduler *theSched = TScheduler::Ptr();
       
   543         GicDistributor* gicDist = (GicDistributor* )theSched->i_GicDistAddr;
       
   544             
       
   545         for( TInt nCpu(0); nCpu < d.iMaxCpus; nCpu++ )
       
   546             {
       
   547             if( nCpu != currCpu )
       
   548                 {
       
   549                 gicDist->iSoftIrq = ( 0x10000 << nCpu ) | (KIntProfilerBase + nCpu);
       
   550                 }
       
   551             // post-sampling for CPUs with specifically generated interrupts
       
   552             postSampleNeeded += d.iSamplers[nCpu]->PostSampleNeeded();
       
   553             }
       
   554         arm_dsb();
       
   555 #endif  
       
   556         // then sample the rest of non-cpu samplers
       
   557         for(TInt i(d.iMaxCpus);i<KSamplerAmount;i++)
       
   558             {
       
   559             if(d.iSamplers[i]->iEnabled)
       
   560                 {
       
   561                 d.iSamplers[i]->Sample();
       
   562                 postSampleNeeded += d.iSamplers[i]->PostSampleNeeded();
       
   563                 }
       
   564             }
       
   565 			
       
   566 		if(postSampleNeeded > 0 && d.doingDfc == 0)
       
   567 		    {
       
   568 			d.doingDfc++;
       
   569 			d.iNewDfc.Add();
       
   570 
       
   571 			d.sampleRunning--;
       
   572 			return;
       
   573             }
       
   574 		d.sampleRunning--;
       
   575         }
       
   576 	else if (d.iState == EStopping && d.sampleRunning == 0)
       
   577 	    {
       
   578 		// add a dfc for this final time
       
   579 		d.iNewDfc.Add();
       
   580         Kern::Printf("DGeneralsDriver::Sample - sampling added to dfc queue");
       
   581         }
       
   582 	else
       
   583 	    {
       
   584 		// the previous sample has not finished,
       
   585 		Kern::Printf("DGeneralsDriver::NewDoProfilerProfile - Profiler Sampler Error - interrupted before finished sampling!!");
       
   586         }
       
   587         LOGSTRING("DGeneralsDriver::NewDoProfilerProfile - exit");
       
   588     }
       
   589 
       
   590 
       
   591 
       
   592 void DGeneralsDriver::Sample(TAny* aPtr)
       
   593     {
       
   594     LOGSTRING("DGeneralsDriver::Sample - entry");
       
   595 
       
   596 #ifdef __SMP__
       
   597     DGeneralsDriver& d=*(DGeneralsDriver*)aPtr;
       
   598 
       
   599 //    TInt currCpu(NKern::CurrentCpu());
       
   600 
       
   601     // sample the current cpu load
       
   602 //    if(d.iSamplers[currCpu]->iEnabled)
       
   603 //        {
       
   604         d.iSamplers[NKern::CurrentCpu()]->Sample();
       
   605 //        postSampleNeeded += d.iSamplers[currCpu]->PostSampleNeeded();
       
   606 //        }
       
   607 #endif
       
   608     LOGSTRING("DGeneralsDriver::Sample - exit");
       
   609     }
       
   610 /*
       
   611  *	This function is run when any of the samplers
       
   612  *	requires post sampling
       
   613  */
       
   614 void DGeneralsDriver::NewDoDfc(TAny* pointer)
       
   615     {
       
   616 	DGeneralsDriver& d(*((DGeneralsDriver*)pointer));
       
   617 	
       
   618 	if(d.iState == ERunning)
       
   619 	    {
       
   620 		// for all enabled samplers, perform
       
   621 		// post sample if needed
       
   622 		for(TInt i(0);i<KSamplerAmount;i++)
       
   623 		    {
       
   624 			if(d.iSamplers[i]->iEnabled)
       
   625 			    {
       
   626 				if(d.iSamplers[i]->PostSampleNeeded())
       
   627 				    {
       
   628 					d.iSamplers[i]->PostSample();
       
   629                     }
       
   630                 }
       
   631             }
       
   632 		d.doingDfc--;
       
   633         }
       
   634 
       
   635 	else if(d.iState == EStopping)
       
   636 	    {
       
   637 		// for all enabled samplers,
       
   638 		// perform end sampling
       
   639 		TBool releaseBuffer(false);
       
   640 		for(TInt i(0);i<KSamplerAmount;i++)
       
   641 		    {
       
   642 			if(d.iSamplers[i]->iEnabled)
       
   643 			    {
       
   644 				LOGSTRING("DGeneralsDriver::NewDoDfc() - ending");
       
   645 				// perform end sampling for all samplers
       
   646 				// stream mode samplers may be pending, if they
       
   647 				// are still waiting for another client buffer
       
   648 				if(d.iSamplers[i]->EndSampling() == KErrNotReady) 
       
   649 				    {
       
   650 					LOGSTRING("DGeneralsDriver::NewDoDfc() - stream data pending");
       
   651 					releaseBuffer = true;
       
   652                     }
       
   653 				else 
       
   654 				    {
       
   655 					LOGSTRING("DGeneralsDriver::NewDoDfc() - no data pending");
       
   656 					releaseBuffer = true;
       
   657                     }		
       
   658                 }
       
   659             }
       
   660 
       
   661 		// At the end, once all the samplers are gone through, the buffer should be released
       
   662 		if (true == releaseBuffer) 
       
   663 		    {
       
   664 			LOGSTRING("DGeneralsDriver::NewDoDfc() - release the buffer");
       
   665 			d.iSampleStream.ReleaseIfPending();	
       
   666             }
       
   667 		
       
   668 		d.iState = EStopped;
       
   669 		if(d.iEndRequestStatus != 0 && d.iClient != 0)
       
   670 		    {
       
   671 			// sampling has ended
       
   672 			Kern::RequestComplete(d.iClient,d.iEndRequestStatus,KErrNone);
       
   673             }
       
   674         }
       
   675     }
       
   676 
       
   677 
       
   678 /*
       
   679  *	All controls are handled here
       
   680  */
       
   681  
       
   682 void DGeneralsDriver::HandleMsg(TMessageBase* aMsg)
       
   683     {
       
   684 	TInt r(KErrNone);
       
   685 	TThreadMessage& m(*(TThreadMessage*)aMsg);
       
   686 
       
   687 	LOGSTRING5("DGeneralsDriver::HandleMsg 0x%x 0x%x 0x%x 0x%x",m.Int0(),m.Int1(),m.Int2(),m.Int3());
       
   688 	
       
   689 	if(m.iValue == (TInt)ECloseMsg)
       
   690 	    {
       
   691 		LOGSTRING("DGeneralsDriver::HandleMsg - received close message");
       
   692 		iTimer.Cancel();
       
   693 		iNewDfc.Cancel();
       
   694 
       
   695 		m.Complete(KErrNone,EFalse);
       
   696 		iMsgQ.CompleteAll(KErrServerTerminated);
       
   697 		LOGSTRING("DGeneralsDriver::HandleMsg - cleaned up the driver!");
       
   698 		return;
       
   699         }
       
   700 
       
   701 	if (m.Client()!=iClient)
       
   702 	    {
       
   703 		LOGSTRING("DGeneralsDriver::HandleMsg - ERROR, wrong client");
       
   704 		m.PanicClient(_L("GENERALSSAMPLER"),EAccessDenied);
       
   705 		return;
       
   706         }
       
   707 
       
   708 	TInt id(m.iValue);
       
   709 	switch(id)
       
   710 	    {
       
   711 		 //Controls are handled here
       
   712 		case RPluginSampler::EMarkTraceActive:
       
   713 			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceActive");
       
   714 			r = MarkTraceActive((TInt)m.Int0());
       
   715 			break;
       
   716 
       
   717 		case RPluginSampler::EOutputSettingsForTrace:
       
   718 			LOGSTRING("DGeneralsDriver::HandleMsg - EOutputSettingsForTrace");
       
   719 			r = OutputSettingsForTrace((TInt)m.Int0(),(TInt)m.Int1());
       
   720 			break;
       
   721 
       
   722 		case RPluginSampler::EAdditionalTraceSettings:
       
   723 			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings");
       
   724 			r = AdditionalTraceSettings((TInt)m.Int0(),(TInt)m.Int1());
       
   725 			break;
       
   726 
       
   727 		case RPluginSampler::EAdditionalTraceSettings2:
       
   728 			LOGSTRING("DGeneralsDriver::HandleMsg - EAdditionalTraceSettings2");
       
   729 			r = AdditionalTraceSettings2((TInt)m.Int0(),(TInt)m.Int1());
       
   730 			break;
       
   731 			
       
   732 		case RPluginSampler::ESetSamplingPeriod:
       
   733 		    LOGSTRING2("DGeneralsDriver::HandleMsg - ESetSamplingPeriod %d", (TInt)m.Int1());
       
   734 			r = SetSamplingPeriod((TInt)m.Int0(),(TInt)m.Int1());
       
   735 			break;
       
   736 			
       
   737 		case RPluginSampler::EMarkTraceInactive:
       
   738 			LOGSTRING("DGeneralsDriver::HandleMsg - EMarkTraceInactive");
       
   739 			r = MarkTraceInactive((TInt)m.Int0());
       
   740 			break;
       
   741 
       
   742 		case RPluginSampler::ESample:
       
   743 			LOGSTRING("DGeneralsDriver::HandleMsg - ESample");
       
   744 			//r = Sample();  // hack. Original implementation of sample just returned 0
       
   745 			r = 0;
       
   746 			break;
       
   747 
       
   748 		case RPluginSampler::EStartSampling:
       
   749 			LOGSTRING("DGeneralsDriver::HandleMsg - EStartSampling");
       
   750 			r = StartSampling();
       
   751 			break;
       
   752 
       
   753 		case RPluginSampler::EGetSampleTime:
       
   754 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSampleTime");
       
   755 			r = GetSampleTime(reinterpret_cast<TUint32*>(m.Ptr0()));
       
   756 			break;
       
   757 
       
   758 		case RPluginSampler::EGetSamplerVersion:
       
   759 			LOGSTRING("DGeneralsDriver::HandleMsg - EGetSamplerVersion");
       
   760 			r = GetSamplerVersion(reinterpret_cast<TDes*>(m.Ptr0()));
       
   761 			break;
       
   762 		
       
   763 		case RPluginSampler::ECancelStreamRead:
       
   764 			LOGSTRING("DGeneralsDriver::HandleMsg - ECancelStreamRead");
       
   765 			iStreamReadCancelStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
       
   766 			r = ProcessStreamReadCancel();
       
   767 			break;
       
   768 
       
   769 
       
   770 		 //	Requests are handled here
       
   771 
       
   772 		case ~RPluginSampler::EStopAndWaitForEnd:
       
   773 			LOGSTRING("DGeneralsDriver::HandleMsg - EStopAndWaitForEnd");
       
   774 			iEndRequestStatus = reinterpret_cast<TRequestStatus*>(m.Ptr0());
       
   775 			r = StopSampling();
       
   776 #ifdef __SMP__
       
   777 			UnbindInterrupts();
       
   778 #endif
       
   779 			break;
       
   780 
       
   781 		case ~RPluginSampler::ERequestFillThisStreamBuffer:
       
   782 			LOGSTRING("DGeneralsDriver::HandleMsg - ERequestFillThisStreamBuffer");			
       
   783 			r = ProcessStreamReadRequest(	reinterpret_cast<TBapBuf*>(m.Ptr1()),
       
   784 											reinterpret_cast<TRequestStatus*>(m.Ptr0()));
       
   785 			break;
       
   786 
       
   787 		default:
       
   788 			LOGSTRING2("DGeneralsDriver::HandleMsg - ERROR, unknown command %d",id);
       
   789 			r = KErrNotSupported;
       
   790 			break;
       
   791         }
       
   792 
       
   793 	LOGSTRING("DGeneralsDriver::HandleMsg - Completed");
       
   794 	m.Complete(r,ETrue);
       
   795     }
       
   796 
       
   797 #ifdef __SMP__
       
   798 inline void DGeneralsDriver::UnbindInterrupts()
       
   799     {
       
   800     TInt err(0);
       
   801 
       
   802     // disable interrupts when sampling stops, enabled again on start
       
   803     err = NKern::InterruptDisable(KIntProfilerBase - 32);
       
   804     if(err < 0)
       
   805         Kern::Printf(" InterruptDisable KIntProfilerBase - 32 ret = %d", err );
       
   806     
       
   807     err = NKern::InterruptDisable(KIntProfilerBase + 1 - 32);
       
   808     if(err < 0)
       
   809         Kern::Printf(" InterruptDisable KIntProfilerBase + 1 - 32 ret = %d", err );
       
   810 
       
   811     err = NKern::InterruptDisable(KIntProfilerBase + 2 - 32);
       
   812     if(err < 0)
       
   813         Kern::Printf(" InterruptDisable KIntProfilerBase + 2 - 32 ret = %d", err );
       
   814 
       
   815     err = NKern::InterruptDisable(KIntProfilerBase + 3 - 32);
       
   816     if(err < 0)
       
   817         Kern::Printf(" InterruptDisable KIntProfilerBase + 3 - 32 ret = %d", err );
       
   818     
       
   819 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase - 32=%d", KIntProfilerBase -32 );
       
   820     err = NKern::InterruptUnbind( KIntProfilerBase - 32);
       
   821     if(err < 0)
       
   822         Kern::Printf(" InterruptUnbind KIntProfilerBase - 32 ret = %d", err );
       
   823     
       
   824 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 1 - 32=%d", KIntProfilerBase + 1-32 );
       
   825     err = NKern::InterruptUnbind( KIntProfilerBase + 1 - 32);
       
   826     if(err < 0)
       
   827         Kern::Printf(" InterruptUnbind KIntProfilerBase + 1 - 32 ret = %d", err );
       
   828 
       
   829 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 2 - 32=%d", KIntProfilerBase + 2 - 32 );
       
   830     err = NKern::InterruptUnbind(KIntProfilerBase + 2 - 32);
       
   831     if(err < 0)
       
   832         Kern::Printf(" InterruptUnbind KIntProfilerBase + 2 - 32 ret = %d", err );
       
   833 
       
   834 //    Kern::Printf(" > Interrupt::InterruptBind KIntProfilerBase + 3 - 32=%d", KIntProfilerBase + 3 - 32 );
       
   835     err = NKern::InterruptUnbind(KIntProfilerBase + 3 - 32);
       
   836     if(err < 0)
       
   837         Kern::Printf(" InterruptUnbind KIntProfilerBase + 3 - 32 ret = %d", err );
       
   838 
       
   839     }
       
   840 #endif
       
   841 
       
   842 inline TInt DGeneralsDriver::ProcessStreamReadRequest(TBapBuf* aBuf,TRequestStatus* aStatus)
       
   843 	{
       
   844 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - entry");
       
   845 	
       
   846 	// a new sample buffer has been received from the client
       
   847 	iSampleStream.AddSampleBuffer(aBuf,aStatus);
       
   848 	
       
   849 	// check if we are waiting for the last data to be written to the client
       
   850 	if(iState == EStopped)
       
   851 	    {
       
   852 		LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest state = EStopped");
       
   853 	
       
   854 		// sampling has stopped and stream read cancel is pending
       
   855 		// try to perform the end sampling procedure again
       
   856 		TBool releaseBuffer(false);
       
   857 		for(TInt i(0);i<KSamplerAmount;i++)
       
   858 		    {
       
   859 			// only for all enabled samplers that have stream output mode
       
   860 			if(iSamplers[i]->iEnabled /*&& samplers[i]->outputMode == 2*/)
       
   861 			    {
       
   862 				//TInt pending = 0;
       
   863 				// stream mode samplers may be pending, if they
       
   864 				// are still waiting for another client buffer,
       
   865 				// in that case, the request should be completed already
       
   866 				if(iSamplers[i]->EndSampling() == KErrNotReady) 
       
   867 				    {
       
   868 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - still data pending");
       
   869 					releaseBuffer = true;
       
   870                     }
       
   871 				else 
       
   872 				    {
       
   873 					LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - no data pending");
       
   874 					releaseBuffer = true;
       
   875                     }
       
   876                 }
       
   877             }
       
   878 		// At the end, once all the samplers are gone through, the buffer should be released
       
   879 		if (true == releaseBuffer) 
       
   880 		    {
       
   881 			LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - all data copied, release the buffer");
       
   882 			iSampleStream.ReleaseIfPending();
       
   883 		    }
       
   884         }
       
   885 	LOGSTRING("DGeneralsDriver::ProcessStreamReadRequest - exit");
       
   886 	
       
   887 	return KErrNone;
       
   888 	}
       
   889 
       
   890 
       
   891 /*
       
   892  *	Mark traces active or inactive, this can be done
       
   893  *	only if sampling is not running
       
   894  */
       
   895 
       
   896 inline TInt DGeneralsDriver::MarkTraceActive(TInt samplerIdToActivate)
       
   897 	{
       
   898 	LOGSTRING2("DGeneralsDriver::MarkTraceActive %d",samplerIdToActivate);
       
   899 
       
   900 	TInt cpus(0);
       
   901 #ifdef __SMP__
       
   902 	cpus = NKern::NumberOfCpus();
       
   903 	if( samplerIdToActivate == PROFILER_GPP_SAMPLER_ID )
       
   904 	    {
       
   905 	    for(TInt cpu(0);cpu<cpus;cpu++)
       
   906 	         {
       
   907 	         Kern::Printf("DGeneralsDriver::MarkTraceActive - activating CPU %d",cpu);
       
   908 	         iSamplers[cpu]->SetEnabledFlag(true);
       
   909 	         }
       
   910 	    return KErrNone;
       
   911 	    }
       
   912 #endif
       
   913 	for(TInt i(cpus);i<KSamplerAmount;i++)
       
   914 	    {
       
   915 		if(iSamplers[i]->iSamplerId == samplerIdToActivate)
       
   916 		    {
       
   917 			iSamplers[i]->SetEnabledFlag(true);
       
   918 			return KErrNone;
       
   919             }
       
   920         }
       
   921 
       
   922 	LOGSTRING2("DGeneralsDriver::MarkTraceActive - %d not supported",samplerIdToActivate);
       
   923 	return KErrNotSupported;
       
   924 	}
       
   925 
       
   926 inline TInt DGeneralsDriver::MarkTraceInactive(TInt samplerIdToDisable)
       
   927 	{
       
   928 	LOGSTRING2("DGeneralsDriver::MarkTraceInactive %d",samplerIdToDisable);
       
   929 
       
   930     TInt cpus(0);
       
   931 #ifdef __SMP__
       
   932     cpus = NKern::NumberOfCpus();
       
   933     if( samplerIdToDisable == PROFILER_GPP_SAMPLER_ID )
       
   934         {
       
   935         for(TInt cpu(0);cpu<cpus;cpu++)
       
   936              {
       
   937              iSamplers[cpu]->SetEnabledFlag(false);
       
   938              }
       
   939         return KErrNone;
       
   940         }
       
   941 #endif
       
   942     for(TInt i(cpus);i<KSamplerAmount;i++)
       
   943 	    {
       
   944 		if(iSamplers[i]->iSamplerId == samplerIdToDisable)
       
   945 		    {
       
   946 			iSamplers[i]->SetEnabledFlag(false);
       
   947 			return KErrNone;
       
   948             }
       
   949         }
       
   950 
       
   951 	LOGSTRING2("DGeneralsDriver::MarkTraceInactive - %d not supported",samplerIdToDisable);
       
   952 	return KErrNotSupported;
       
   953 	}
       
   954 
       
   955 /*
       
   956  *	Set output settings for a trace
       
   957  */
       
   958  
       
   959 inline TInt DGeneralsDriver::OutputSettingsForTrace(TInt samplerId,TInt settings)
       
   960 	{
       
   961 	LOGSTRING3("DGeneralsDriver::OutputSettingsForTrace id:%d set:%d",samplerId,settings);
       
   962 
       
   963     TInt cpus(0);
       
   964 #ifdef __SMP__
       
   965     cpus = NKern::NumberOfCpus();
       
   966     if( samplerId == PROFILER_GPP_SAMPLER_ID )
       
   967         {
       
   968         for(TInt cpu(0);cpu<cpus;cpu++)
       
   969              {
       
   970              iSamplers[cpu]->SetOutputCombination(settings);
       
   971              }
       
   972         return KErrNone;
       
   973         }
       
   974 #endif
       
   975     for(TInt i(cpus);i<KSamplerAmount;i++)
       
   976 	    {
       
   977 		if(iSamplers[i]->iSamplerId == samplerId)
       
   978 		    {
       
   979 			iSamplers[i]->SetOutputCombination(settings);
       
   980 			return KErrNone;
       
   981 		    }
       
   982 	    }
       
   983 
       
   984 	return KErrNotSupported;	
       
   985 	}
       
   986 
       
   987 /*
       
   988  *	Set additional settings for a trace
       
   989  */
       
   990 
       
   991 inline TInt DGeneralsDriver::AdditionalTraceSettings(TInt samplerId,TInt settings)
       
   992 	{
       
   993 	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
       
   994 
       
   995     TInt cpus(0);
       
   996 #ifdef __SMP__
       
   997     cpus = NKern::NumberOfCpus();
       
   998     if( samplerId == PROFILER_GPP_SAMPLER_ID )
       
   999         {
       
  1000         for(TInt cpu(0);cpu<cpus;cpu++)
       
  1001              {
       
  1002              iSamplers[cpu]->SetAdditionalSettings(settings);
       
  1003              }
       
  1004         return KErrNone;
       
  1005         }
       
  1006 #endif
       
  1007     for(TInt i(cpus);i<KSamplerAmount;i++)
       
  1008 	    {
       
  1009 		if(iSamplers[i]->iSamplerId == samplerId)
       
  1010 		    {
       
  1011 			iSamplers[i]->SetAdditionalSettings(settings);
       
  1012 			return KErrNone;
       
  1013             }
       
  1014         }
       
  1015 
       
  1016 	return KErrNotSupported;	
       
  1017 	}
       
  1018 
       
  1019 inline TInt DGeneralsDriver::AdditionalTraceSettings2(TInt samplerId,TInt settings)
       
  1020 	{
       
  1021 	LOGSTRING3("DGeneralsDriver::SetAdditionalTraceSettings id:%d set:%d",samplerId,settings);
       
  1022 
       
  1023     TInt cpus(0);
       
  1024 #ifdef __SMP__
       
  1025     cpus = NKern::NumberOfCpus();
       
  1026     if( samplerId == PROFILER_GPP_SAMPLER_ID )
       
  1027         {
       
  1028         for(TInt cpu(0);cpu<cpus;cpu++)
       
  1029              {
       
  1030              iSamplers[cpu]->SetAdditionalSettings2(settings);
       
  1031              }
       
  1032         return KErrNone;
       
  1033         }
       
  1034 #endif
       
  1035     for(TInt i(cpus);i<KSamplerAmount;i++)
       
  1036 	    {
       
  1037 		if(iSamplers[i]->iSamplerId == samplerId)
       
  1038 		    {
       
  1039 			iSamplers[i]->SetAdditionalSettings2(settings);
       
  1040 			return KErrNone;
       
  1041 		    }
       
  1042         }
       
  1043 
       
  1044 	return KErrNotSupported;	
       
  1045 	}
       
  1046 
       
  1047 inline TInt DGeneralsDriver::SetSamplingPeriod(TInt samplerId,TInt settings)
       
  1048 	{
       
  1049 	LOGSTRING2("DGeneralsDriver::SetSamplingPeriod - set:%d",settings);
       
  1050 
       
  1051 	TInt cpus(0);
       
  1052 #ifdef __SMP__
       
  1053     cpus = NKern::NumberOfCpus();
       
  1054     if( samplerId == PROFILER_GPP_SAMPLER_ID )
       
  1055         {
       
  1056         for(TInt cpu(0);cpu<cpus;cpu++)
       
  1057              {
       
  1058              iSamplers[cpu]->SetSamplingPeriod(settings);
       
  1059              }
       
  1060         return KErrNone;
       
  1061         }
       
  1062 #endif
       
  1063     for(TInt i(cpus);i<KSamplerAmount;i++)
       
  1064 	    {
       
  1065 		if(iSamplers[i]->iSamplerId == samplerId)
       
  1066 		    {
       
  1067 			iSamplers[i]->SetSamplingPeriod(settings);
       
  1068 			return KErrNone;
       
  1069 		    }
       
  1070 	    }
       
  1071 
       
  1072 	return KErrNotSupported;	
       
  1073 	}
       
  1074 
       
  1075 /*
       
  1076  *	Mark traces active or inactive, this can be done
       
  1077  *	only if sampling is not running
       
  1078  */
       
  1079  
       
  1080 TInt DGeneralsDriver::StartSampling()
       
  1081 	{
       
  1082 	LOGSTRING("DGeneralsDriver::StartSampling");
       
  1083 
       
  1084 	if(iState == EStopped)
       
  1085 		{
       
  1086 		// reset iSampleStartTimeProp property value
       
  1087 		iSampleStartTime = NKern::TickCount();	// get the system tick value for sync purposes 
       
  1088 #ifdef __SMP__
       
  1089 		iStartTime = (iSampleStartTime & 0xfffffff0);
       
  1090 #endif
       
  1091 		TInt r(iSampleStartTimeProp.Set(iSampleStartTime));
       
  1092 		
       
  1093 		Kern::Printf(("PIPROF SAMPLE TICK, #0")); // for remote profiling with Profiler Activator
       
  1094 		
       
  1095 		// reset all enabled samplers
       
  1096 		for(TInt i(0);i<KSamplerAmount;i++)
       
  1097 			{
       
  1098 			if(iSamplers[i]->iEnabled)
       
  1099 				{
       
  1100 				// reset with stream option
       
  1101 #ifndef __SMP__
       
  1102                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, sync offset %d"), 0);
       
  1103 				iSamplers[i]->Reset(&iSampleStream, 0);
       
  1104 #else
       
  1105                 Kern::Printf(("DGeneralsDriver::StartSampling - stream reset for generals driver, start time %d"), iStartTime);
       
  1106                 iSamplers[i]->Reset(&iSampleStream, iStartTime);
       
  1107 #endif
       
  1108 				}
       
  1109 			}
       
  1110 
       
  1111 		NewStart(gppSampler.GetPeriod());
       
  1112 		return KErrNone;
       
  1113 		}
       
  1114 	else
       
  1115 		{
       
  1116 		return KErrGeneral;
       
  1117 		}
       
  1118 	}
       
  1119 
       
  1120 /*
       
  1121  *  Mark traces active or inactive, this can be done
       
  1122  *  only if sampling is not running
       
  1123  */
       
  1124  
       
  1125 TInt DGeneralsDriver::StopSampling()
       
  1126     {
       
  1127     LOGSTRING("DGeneralsDriver::StopSampling");
       
  1128 
       
  1129     if(iState == ERunning)
       
  1130         {
       
  1131         this->iState = EStopping;
       
  1132         // reset all enabled samplers
       
  1133         for(TInt i(0);i<KSamplerAmount;i++)
       
  1134             {
       
  1135             // do the reset only for memory sampler
       
  1136             if(iSamplers[i]->iEnabled && iSamplers[i]->iSamplerId == 4)
       
  1137                 {
       
  1138                 // reset with stream option
       
  1139                 LOGTEXT(("DGeneralsDriver::StopSampling - stream reset for samplers"));
       
  1140                 iSamplers[i]->Reset(&iSampleStream, 999999);
       
  1141                 }
       
  1142             }
       
  1143 
       
  1144         return KErrNone;
       
  1145         }
       
  1146     else
       
  1147         {
       
  1148         return KErrGeneral;
       
  1149         }
       
  1150     }
       
  1151 
       
  1152