os/kernelhwsrv/kerneltest/e32test/benchmark/rt_latency.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/benchmark/rt_latency.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,154 @@
     1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <e32test.h>
    1.20 +
    1.21 +#include "bm_suite.h"
    1.22 +
    1.23 +class RTLatency : public BMProgram
    1.24 +	{
    1.25 +
    1.26 +	struct Measurement
    1.27 +		{
    1.28 +		RBMChannel::TMode	iMode;
    1.29 +		TPtrC				iName;
    1.30 +		TBool				iForcePSwitch;
    1.31 +
    1.32 +		Measurement(RBMChannel::TMode aMode, const TDesC& aName, TBool aForcePSwitch = EFalse) : 
    1.33 +			iMode(aMode), iName(aName), iForcePSwitch(aForcePSwitch) {}
    1.34 +		};
    1.35 +
    1.36 +public :
    1.37 +	RTLatency() : BMProgram(_L("Real-Time Latency"))
    1.38 +		{}
    1.39 +	virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount);
    1.40 +
    1.41 +	static TBMResult	iResults[];
    1.42 +	static Measurement	iMeasurements[];
    1.43 +
    1.44 +	void Perform(RBMChannel::TMode, TBMResult*, TBMUInt64 aIter, TBool aForcePSwitch);
    1.45 +	static TInt Child(TAny*);
    1.46 +	};
    1.47 +
    1.48 +RTLatency::Measurement		RTLatency::iMeasurements[] =
    1.49 +	{ 
    1.50 +		Measurement(RBMChannel::EInterruptLatency, _L("Interrupt Latency")),
    1.51 +		Measurement(RBMChannel::EKernelPreemptionLatency, _L("Kernel Thread Preemption Latency (Idle)")),
    1.52 +		Measurement(RBMChannel::EKernelPreemptionLatency, _L("Kernel Thread Preemption Latency(Busy)"), ETrue),
    1.53 +		Measurement(RBMChannel::EUserPreemptionLatency, _L("User Thread Preemption Latency (Idle)")),
    1.54 +		Measurement(RBMChannel::EUserPreemptionLatency, _L("User Thread Preemption Latency (Busy)"), ETrue),
    1.55 +		Measurement(RBMChannel::ENTimerJitter, _L("NTimer Jitter")),
    1.56 +		Measurement(RBMChannel::ETimerStampOverhead, _L("Getting Time Stamp Overhead"))
    1.57 +	};
    1.58 +TBMResult	RTLatency::iResults[sizeof(RTLatency::iMeasurements)/sizeof(RTLatency::iMeasurements[0])];
    1.59 +
    1.60 +static RTLatency rtLatency;
    1.61 +
    1.62 +struct ChildArgs : public TBMSpawnArgs
    1.63 +	{
    1.64 +	RSemaphore iSem;
    1.65 +	ChildArgs () : TBMSpawnArgs(RTLatency::Child, KBMPriorityLow, ETrue, sizeof(*this))
    1.66 +		{
    1.67 +		TInt r = KErrNone;
    1.68 +		do
    1.69 +			{		//"Bm_SuiteSemaphore" is created/deleted a number of times during the test.
    1.70 +			if (r)	//If kernel did not clean up the previous instance, wait a sec and retry.
    1.71 +				User::After(1000000);
    1.72 +			r = iSem.CreateGlobal(_L("Bm_SuiteSemaphore"), 0);
    1.73 +			}
    1.74 +		while(KErrAlreadyExists == r);
    1.75 +
    1.76 +		BM_ERROR(r, r == KErrNone);
    1.77 +		}
    1.78 +	void ChildOpen()
    1.79 +		{	
    1.80 +		iSem.Duplicate(iParent);
    1.81 +		}
    1.82 +	~ChildArgs ()
    1.83 +		{
    1.84 +		iSem.Close();
    1.85 +		}
    1.86 +	};
    1.87 +
    1.88 +//
    1.89 +// Child process entry point.
    1.90 +//
    1.91 +TInt RTLatency::Child(TAny* ptr)
    1.92 +	{
    1.93 +	ChildArgs* ca = (ChildArgs*) ptr;
    1.94 +		// get handles to all objects shared with the parent
    1.95 +	ca->ChildOpen();
    1.96 +		// signal the parent that the child is ready
    1.97 +	ca->iSem.Signal();
    1.98 +		// loop forever
    1.99 +	for(;;) {}
   1.100 +	}
   1.101 +
   1.102 +void RTLatency::Perform(RBMChannel::TMode aMode, TBMResult* aResult, TBMUInt64 aIter, TBool aForcePSwitch)
   1.103 +	{
   1.104 +	ChildArgs ca;
   1.105 +	MBMChild* child = NULL;
   1.106 +	if (aForcePSwitch)
   1.107 +		{
   1.108 +			// spawn a busy running low-pririty child process
   1.109 +		child = rtLatency.SpawnChild(&ca);
   1.110 +		ca.iSem.Wait();
   1.111 +		}
   1.112 +
   1.113 +	RBMChannel ch;
   1.114 +	TInt r = ch.Open(aMode);
   1.115 +	if(r==KErrInUse)
   1.116 +		return; // Assume that resources are being used for other forms of latency testing
   1.117 +	BM_ERROR(r, r == KErrNone);
   1.118 +	while(aIter--) 
   1.119 +		{
   1.120 +			// request an interrupt
   1.121 +		ch.RequestInterrupt();
   1.122 +		TBMTicks ticks;
   1.123 +			// wait for the result. At this point the child becomes running.
   1.124 +		ch.Result(&ticks);
   1.125 +		aResult->Cumulate(ticks);
   1.126 +		}
   1.127 +	ch.Close();
   1.128 +
   1.129 +	if (aForcePSwitch)
   1.130 +		{
   1.131 +		child->Kill();
   1.132 +		child->WaitChildExit();
   1.133 +		}
   1.134 +	}
   1.135 +
   1.136 +					
   1.137 +TBMResult* RTLatency::Run(TBMUInt64 aIter, TInt* aCount)
   1.138 +	{
   1.139 +	TInt count = sizeof(iResults)/sizeof(iResults[0]);
   1.140 +
   1.141 +	for (TInt i = 0; i < count; ++i)
   1.142 +		{
   1.143 +		iResults[i].Reset(iMeasurements[i].iName);
   1.144 +		Perform(iMeasurements[i].iMode, &iResults[i], aIter, iMeasurements[i].iForcePSwitch);
   1.145 +		iResults[i].Update();
   1.146 +		}
   1.147 +	
   1.148 +	*aCount = count;
   1.149 +	return iResults;
   1.150 +	}
   1.151 +
   1.152 +void AddrtLatency()
   1.153 +	{
   1.154 +	BMProgram* next = bmSuite;
   1.155 +	bmSuite=(BMProgram*)&rtLatency;
   1.156 +	bmSuite->Next()=next;
   1.157 +	}