diff -r 000000000000 -r a41df078684a kerneltest/e32test/benchmark/rt_latency.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/benchmark/rt_latency.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,154 @@ +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include + +#include "bm_suite.h" + +class RTLatency : public BMProgram + { + + struct Measurement + { + RBMChannel::TMode iMode; + TPtrC iName; + TBool iForcePSwitch; + + Measurement(RBMChannel::TMode aMode, const TDesC& aName, TBool aForcePSwitch = EFalse) : + iMode(aMode), iName(aName), iForcePSwitch(aForcePSwitch) {} + }; + +public : + RTLatency() : BMProgram(_L("Real-Time Latency")) + {} + virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount); + + static TBMResult iResults[]; + static Measurement iMeasurements[]; + + void Perform(RBMChannel::TMode, TBMResult*, TBMUInt64 aIter, TBool aForcePSwitch); + static TInt Child(TAny*); + }; + +RTLatency::Measurement RTLatency::iMeasurements[] = + { + Measurement(RBMChannel::EInterruptLatency, _L("Interrupt Latency")), + Measurement(RBMChannel::EKernelPreemptionLatency, _L("Kernel Thread Preemption Latency (Idle)")), + Measurement(RBMChannel::EKernelPreemptionLatency, _L("Kernel Thread Preemption Latency(Busy)"), ETrue), + Measurement(RBMChannel::EUserPreemptionLatency, _L("User Thread Preemption Latency (Idle)")), + Measurement(RBMChannel::EUserPreemptionLatency, _L("User Thread Preemption Latency (Busy)"), ETrue), + Measurement(RBMChannel::ENTimerJitter, _L("NTimer Jitter")), + Measurement(RBMChannel::ETimerStampOverhead, _L("Getting Time Stamp Overhead")) + }; +TBMResult RTLatency::iResults[sizeof(RTLatency::iMeasurements)/sizeof(RTLatency::iMeasurements[0])]; + +static RTLatency rtLatency; + +struct ChildArgs : public TBMSpawnArgs + { + RSemaphore iSem; + ChildArgs () : TBMSpawnArgs(RTLatency::Child, KBMPriorityLow, ETrue, sizeof(*this)) + { + TInt r = KErrNone; + do + { //"Bm_SuiteSemaphore" is created/deleted a number of times during the test. + if (r) //If kernel did not clean up the previous instance, wait a sec and retry. + User::After(1000000); + r = iSem.CreateGlobal(_L("Bm_SuiteSemaphore"), 0); + } + while(KErrAlreadyExists == r); + + BM_ERROR(r, r == KErrNone); + } + void ChildOpen() + { + iSem.Duplicate(iParent); + } + ~ChildArgs () + { + iSem.Close(); + } + }; + +// +// Child process entry point. +// +TInt RTLatency::Child(TAny* ptr) + { + ChildArgs* ca = (ChildArgs*) ptr; + // get handles to all objects shared with the parent + ca->ChildOpen(); + // signal the parent that the child is ready + ca->iSem.Signal(); + // loop forever + for(;;) {} + } + +void RTLatency::Perform(RBMChannel::TMode aMode, TBMResult* aResult, TBMUInt64 aIter, TBool aForcePSwitch) + { + ChildArgs ca; + MBMChild* child = NULL; + if (aForcePSwitch) + { + // spawn a busy running low-pririty child process + child = rtLatency.SpawnChild(&ca); + ca.iSem.Wait(); + } + + RBMChannel ch; + TInt r = ch.Open(aMode); + if(r==KErrInUse) + return; // Assume that resources are being used for other forms of latency testing + BM_ERROR(r, r == KErrNone); + while(aIter--) + { + // request an interrupt + ch.RequestInterrupt(); + TBMTicks ticks; + // wait for the result. At this point the child becomes running. + ch.Result(&ticks); + aResult->Cumulate(ticks); + } + ch.Close(); + + if (aForcePSwitch) + { + child->Kill(); + child->WaitChildExit(); + } + } + + +TBMResult* RTLatency::Run(TBMUInt64 aIter, TInt* aCount) + { + TInt count = sizeof(iResults)/sizeof(iResults[0]); + + for (TInt i = 0; i < count; ++i) + { + iResults[i].Reset(iMeasurements[i].iName); + Perform(iMeasurements[i].iMode, &iResults[i], aIter, iMeasurements[i].iForcePSwitch); + iResults[i].Update(); + } + + *aCount = count; + return iResults; + } + +void AddrtLatency() + { + BMProgram* next = bmSuite; + bmSuite=(BMProgram*)&rtLatency; + bmSuite->Next()=next; + }