diff -r 000000000000 -r a41df078684a kerneltest/e32test/misc/cpumeter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/misc/cpumeter.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,273 @@ +// Copyright (c) 1996-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: +// e32test\misc\cpumeter.cpp +// +// + +#define __E32TEST_EXTENSION__ + +#include +#include +#include +#include "u32std.h" + +RTest test(_L("CPU METER")); + +TBool CpuTimeSupported() + { + TTimeIntervalMicroSeconds time; + TInt err = RThread().GetCpuTime(time); + test(err == KErrNone || err == KErrNotSupported); + return err == KErrNone; + } + +TInt NumberOfCpus() + { + TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0); + test(r>0); + return r; + } + +class CCpuMeter : public CBase + { +public: + CCpuMeter(); + ~CCpuMeter(); + static CCpuMeter* New(); + TInt Construct(); + void Measure(); + void Display(TInt aInterval); +public: + TInt iNumCpus; + TInt iNextMeas; + RThread* iNullThreads; + TTimeIntervalMicroSeconds* iMeas[2]; + TInt* iDelta; + }; + +CCpuMeter::CCpuMeter() + { + } + +CCpuMeter::~CCpuMeter() + { + TInt i; + if (iNullThreads) + { + for (i=0; i0) + tname.AppendNum(i); + TFindThread ft(tname); + test_KErrNone(ft.Next(tname2)); + TInt r = iNullThreads[i].Open(ft); + test_KErrNone(r); + iNullThreads[i].FullName(tname2); + test.Printf(_L("Found and opened %S\n"), &tname2); + } + for (i=0; iConstruct(); + if (r!=KErrNone) + { + delete p; + return 0; + } + return p; + } + +void CCpuMeter::Measure() + { + TInt i; + for (i=0; i buf; + TInt i; + for (i=0; i1000) + dv=1000; + buf.AppendFormat(_L(" %4d"),dv); + } + buf.Append(TChar('\n')); + test.Printf(buf); + } + +void UseKernelCpuTime() + { + test.Start(_L("Create CCpuMeter")); + CCpuMeter* m = CCpuMeter::New(); + test_NotNull(m); + TInt iv = 1000500; // on average 1000.5 ms + TRequestStatus s; + CConsoleBase* console = test.Console(); + console->Read(s); + FOREVER + { + User::AfterHighRes(1000000); + m->Measure(); + m->Display(iv); + while (s!=KRequestPending) + { + User::WaitForRequest(s); + TKeyCode k = console->KeyCode(); + if (k == EKeyEscape) + { + delete m; + return; + } + console->Read(s); + } + } + } + + + +TUint32 NopCount=0; +TUint MaxCycles; +_LIT(KLitThreadName,"IdleThread"); +extern TInt CountNops(TAny*); + +void MeasureByNOPs() + { + test.Start(_L("Create thread")); + RThread t; + TInt r=t.Create(KLitThreadName,CountNops,0x1000,NULL,NULL); + test(r==KErrNone); + t.SetPriority(EPriorityAbsoluteVeryLow); + t.Resume(); + + test.Next(_L("Get processor clock frequency")); + TMachineInfoV2Buf buf; + TMachineInfoV2& info=buf(); + r=UserHal::MachineInfo(buf); + test(r==KErrNone); + MaxCycles=info.iProcessorClockInKHz*1000; + test.Printf(_L("Clock frequency %dHz\n"),MaxCycles); + TRequestStatus s; + CConsoleBase* console=test.Console(); + console->Read(s); +#ifdef __WINS__ + TInt timerperiod = 5; + UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"TimerResolution",&timerperiod); +#endif + + FOREVER + { + TUint32 init_count=NopCount; + TUint32 init_ms=User::NTickCount(); + User::After(1000000); + TUint32 final_count=NopCount; + TUint32 final_ms=User::NTickCount(); + TUint32 cycles=final_count-init_count; + TUint32 ms=final_ms-init_ms; +#ifdef __WINS__ + ms*=timerperiod; +#endif + while (s!=KRequestPending) + { + User::WaitForRequest(s); + TKeyCode k=console->KeyCode(); + if (k==EKeyTab) + { + // calibrate + TInt64 inst64 = MAKE_TINT64(0, cycles); + inst64*=1000; + inst64/=MAKE_TINT64(0,ms); + MaxCycles=I64LOW(inst64); + test.Printf(_L("NOPs per second %u\n"),MaxCycles); + } + else if (k==EKeyEscape) + return; + console->Read(s); + } + TInt64 used64=MAKE_TINT64(0, MaxCycles); + + used64-=MAKE_TINT64(0,cycles); + used64*=1000000; + used64/=MAKE_TINT64(0,ms); + used64/=MAKE_TINT64(0, MaxCycles); + test.Printf(_L("%4d\n"),I64INT(used64)); + } + } + + +GLDEF_C TInt E32Main() + { + test.SetLogged(EFalse); + test.Title(); + RThread().SetPriority(EPriorityAbsoluteHigh); + + if (CpuTimeSupported()) + { + UseKernelCpuTime(); + } + if (NumberOfCpus()>1) + { + test.Printf(_L("Needs RThread::GetCpuTime() on SMP systems\n")); + } + else + MeasureByNOPs(); + + return 0; + } +