sl@0: // Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\misc\cpumeter.cpp sl@0: // sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include "u32std.h" sl@0: sl@0: RTest test(_L("CPU METER")); sl@0: sl@0: TBool CpuTimeSupported() sl@0: { sl@0: TTimeIntervalMicroSeconds time; sl@0: TInt err = RThread().GetCpuTime(time); sl@0: test(err == KErrNone || err == KErrNotSupported); sl@0: return err == KErrNone; sl@0: } sl@0: sl@0: TInt NumberOfCpus() sl@0: { sl@0: TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0); sl@0: test(r>0); sl@0: return r; sl@0: } sl@0: sl@0: class CCpuMeter : public CBase sl@0: { sl@0: public: sl@0: CCpuMeter(); sl@0: ~CCpuMeter(); sl@0: static CCpuMeter* New(); sl@0: TInt Construct(); sl@0: void Measure(); sl@0: void Display(TInt aInterval); sl@0: public: sl@0: TInt iNumCpus; sl@0: TInt iNextMeas; sl@0: RThread* iNullThreads; sl@0: TTimeIntervalMicroSeconds* iMeas[2]; sl@0: TInt* iDelta; sl@0: }; sl@0: sl@0: CCpuMeter::CCpuMeter() sl@0: { sl@0: } sl@0: sl@0: CCpuMeter::~CCpuMeter() sl@0: { sl@0: TInt i; sl@0: if (iNullThreads) sl@0: { sl@0: for (i=0; i0) sl@0: tname.AppendNum(i); sl@0: TFindThread ft(tname); sl@0: test_KErrNone(ft.Next(tname2)); sl@0: TInt r = iNullThreads[i].Open(ft); sl@0: test_KErrNone(r); sl@0: iNullThreads[i].FullName(tname2); sl@0: test.Printf(_L("Found and opened %S\n"), &tname2); sl@0: } sl@0: for (i=0; iConstruct(); sl@0: if (r!=KErrNone) sl@0: { sl@0: delete p; sl@0: return 0; sl@0: } sl@0: return p; sl@0: } sl@0: sl@0: void CCpuMeter::Measure() sl@0: { sl@0: TInt i; sl@0: for (i=0; i buf; sl@0: TInt i; sl@0: for (i=0; i1000) sl@0: dv=1000; sl@0: buf.AppendFormat(_L(" %4d"),dv); sl@0: } sl@0: buf.Append(TChar('\n')); sl@0: test.Printf(buf); sl@0: } sl@0: sl@0: void UseKernelCpuTime() sl@0: { sl@0: test.Start(_L("Create CCpuMeter")); sl@0: CCpuMeter* m = CCpuMeter::New(); sl@0: test_NotNull(m); sl@0: TInt iv = 1000500; // on average 1000.5 ms sl@0: TRequestStatus s; sl@0: CConsoleBase* console = test.Console(); sl@0: console->Read(s); sl@0: FOREVER sl@0: { sl@0: User::AfterHighRes(1000000); sl@0: m->Measure(); sl@0: m->Display(iv); sl@0: while (s!=KRequestPending) sl@0: { sl@0: User::WaitForRequest(s); sl@0: TKeyCode k = console->KeyCode(); sl@0: if (k == EKeyEscape) sl@0: { sl@0: delete m; sl@0: return; sl@0: } sl@0: console->Read(s); sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: TUint32 NopCount=0; sl@0: TUint MaxCycles; sl@0: _LIT(KLitThreadName,"IdleThread"); sl@0: extern TInt CountNops(TAny*); sl@0: sl@0: void MeasureByNOPs() sl@0: { sl@0: test.Start(_L("Create thread")); sl@0: RThread t; sl@0: TInt r=t.Create(KLitThreadName,CountNops,0x1000,NULL,NULL); sl@0: test(r==KErrNone); sl@0: t.SetPriority(EPriorityAbsoluteVeryLow); sl@0: t.Resume(); sl@0: sl@0: test.Next(_L("Get processor clock frequency")); sl@0: TMachineInfoV2Buf buf; sl@0: TMachineInfoV2& info=buf(); sl@0: r=UserHal::MachineInfo(buf); sl@0: test(r==KErrNone); sl@0: MaxCycles=info.iProcessorClockInKHz*1000; sl@0: test.Printf(_L("Clock frequency %dHz\n"),MaxCycles); sl@0: TRequestStatus s; sl@0: CConsoleBase* console=test.Console(); sl@0: console->Read(s); sl@0: #ifdef __WINS__ sl@0: TInt timerperiod = 5; sl@0: UserSvr::HalFunction(EHalGroupEmulator,EEmulatorHalIntProperty,(TAny*)"TimerResolution",&timerperiod); sl@0: #endif sl@0: sl@0: FOREVER sl@0: { sl@0: TUint32 init_count=NopCount; sl@0: TUint32 init_ms=User::NTickCount(); sl@0: User::After(1000000); sl@0: TUint32 final_count=NopCount; sl@0: TUint32 final_ms=User::NTickCount(); sl@0: TUint32 cycles=final_count-init_count; sl@0: TUint32 ms=final_ms-init_ms; sl@0: #ifdef __WINS__ sl@0: ms*=timerperiod; sl@0: #endif sl@0: while (s!=KRequestPending) sl@0: { sl@0: User::WaitForRequest(s); sl@0: TKeyCode k=console->KeyCode(); sl@0: if (k==EKeyTab) sl@0: { sl@0: // calibrate sl@0: TInt64 inst64 = MAKE_TINT64(0, cycles); sl@0: inst64*=1000; sl@0: inst64/=MAKE_TINT64(0,ms); sl@0: MaxCycles=I64LOW(inst64); sl@0: test.Printf(_L("NOPs per second %u\n"),MaxCycles); sl@0: } sl@0: else if (k==EKeyEscape) sl@0: return; sl@0: console->Read(s); sl@0: } sl@0: TInt64 used64=MAKE_TINT64(0, MaxCycles); sl@0: sl@0: used64-=MAKE_TINT64(0,cycles); sl@0: used64*=1000000; sl@0: used64/=MAKE_TINT64(0,ms); sl@0: used64/=MAKE_TINT64(0, MaxCycles); sl@0: test.Printf(_L("%4d\n"),I64INT(used64)); sl@0: } sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: test.SetLogged(EFalse); sl@0: test.Title(); sl@0: RThread().SetPriority(EPriorityAbsoluteHigh); sl@0: sl@0: if (CpuTimeSupported()) sl@0: { sl@0: UseKernelCpuTime(); sl@0: } sl@0: if (NumberOfCpus()>1) sl@0: { sl@0: test.Printf(_L("Needs RThread::GetCpuTime() on SMP systems\n")); sl@0: } sl@0: else sl@0: MeasureByNOPs(); sl@0: sl@0: return 0; sl@0: } sl@0: