diff -r 000000000000 -r a41df078684a kerneltest/e32test/benchmark/thread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/benchmark/thread.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,246 @@ +// 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 + +#include "bm_suite.h" + +class Thread : public BMProgram + { +public : + Thread() : BMProgram(_L("Threads")) + {} + virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount); + + typedef void (*MeasurementFunc)(TBMResult*, TBMUInt64 aIter); + struct Measurement + { + MeasurementFunc iFunc; + TPtrC iName; + + Measurement(MeasurementFunc aFunc, const TDesC& aName) : + iFunc(aFunc), iName(aName) {} + }; + + static TBMResult iResults[]; + static Measurement iMeasurements[]; + + static TBMTicks iChildTime; + + static void Creation(TBMResult*, TBMUInt64 aIter); + static TInt CreationChild(TAny*); + static void CreationSuicide(TBMResult*, TBMUInt64 aIter); + static TInt CreationSuicideChild(TAny*); + static void Suicide(TBMResult*, TBMUInt64 aIter); + static TInt SuicideChild(TAny*); + static void Killing(TBMResult*, TBMUInt64 aIter); + static TInt KillingChild(TAny*); + static void SetTls(TBMResult*, TBMUInt64 aIter); + static void GetTls(TBMResult*, TBMUInt64 aIter); + + void EnableCleanup() + { + TInt prio = BMProgram::SetAbsPriority(RThread(), iOrigAbsPriority); + BMProgram::SetAbsPriority(RThread(), prio); + } + }; + +Thread::Measurement Thread::iMeasurements[] = + { + Measurement(&Thread::Creation, _L("Thread Creation Latency")), + Measurement(&Thread::CreationSuicide, _L("Thread Creation Suicide")), + Measurement(&Thread::Suicide, _L("Thread Suicide")), + Measurement(&Thread::Killing, _L("Thread Killing")), + Measurement(&Thread::SetTls, _L("Setting per-thread data")), + Measurement(&Thread::GetTls, _L("Getting per-thread data")) + }; +TBMResult Thread::iResults[sizeof(Thread::iMeasurements)/sizeof(Thread::iMeasurements[0])]; + +TBMTicks Thread::iChildTime; + +static Thread prog; + +void Thread::Creation(TBMResult* aResult, TBMUInt64 aIter) + { + for (TBMUInt64 i = 0; i < aIter; ++i) + { + RThread child; + TRequestStatus st; + TBMTicks t1; + ::bmTimer.Stamp(&t1); + TInt r = child.Create(KNullDesC, Thread::CreationChild, 0x2000, NULL, NULL); + BM_ERROR(r, r == KErrNone); + child.Logon(st); + BMProgram::SetAbsPriority(RThread(), KBMPriorityHigh); + child.Resume(); + User::WaitForRequest(st); + BM_ERROR(st.Int(), st == KErrNone); + aResult->Cumulate(TBMTicksDelta(t1, iChildTime)); + CLOSE_AND_WAIT(child); + prog.EnableCleanup(); + } + } + +TInt Thread::CreationChild(TAny*) + { + ::bmTimer.Stamp(&iChildTime); + return KErrNone; + } + +void Thread::CreationSuicide(TBMResult* aResult, TBMUInt64 aIter) + { + for (TBMUInt64 i = 0; i < aIter; ++i) + { + RThread child; + TRequestStatus st; + TBMTicks t1; + ::bmTimer.Stamp(&t1); + TInt r = child.Create(KNullDesC, Thread::CreationSuicideChild, 0x2000, NULL, NULL); + BM_ERROR(r, r == KErrNone); + child.Logon(st); + BMProgram::SetAbsPriority(RThread(), KBMPriorityLow); + child.Resume(); + User::WaitForRequest(st); + BM_ERROR(st.Int(), st == KErrNone); + TBMTicks t2; + ::bmTimer.Stamp(&t2); + aResult->Cumulate(TBMTicksDelta(t1, t2)); + CLOSE_AND_WAIT(child); + prog.EnableCleanup(); + } + } + +TInt Thread::CreationSuicideChild(TAny*) + { + return KErrNone; + } + +void Thread::Suicide(TBMResult* aResult, TBMUInt64 aIter) + { + for (TBMUInt64 i = 0; i < aIter; ++i) + { + RThread child; + TRequestStatus st; + TInt r = child.Create(KNullDesC, Thread::SuicideChild, 0x2000, NULL, NULL); + BM_ERROR(r, r == KErrNone); + child.Logon(st); + BMProgram::SetAbsPriority(RThread(), KBMPriorityLow); + child.Resume(); + User::WaitForRequest(st); + BM_ERROR(st.Int(), st == KErrNone); + TBMTicks t2; + ::bmTimer.Stamp(&t2); + aResult->Cumulate(TBMTicksDelta(iChildTime, t2)); + CLOSE_AND_WAIT(child); + prog.EnableCleanup(); + } + } + +TInt Thread::SuicideChild(TAny*) + { + ::bmTimer.Stamp(&iChildTime); + return KErrNone; + } + +void Thread::Killing(TBMResult* aResult, TBMUInt64 aIter) + { + for (TBMUInt64 i = 0; i < aIter; ++i) + { + RThread child; + TRequestStatus st; + TInt r = child.Create(KNullDesC, Thread::KillingChild, 0x2000, NULL, NULL); + BM_ERROR(r, r == KErrNone); + child.Logon(st); + BMProgram::SetAbsPriority(RThread(), KBMPriorityHigh); + child.Resume(); + TBMTicks t1; + ::bmTimer.Stamp(&t1); + child.Kill(KErrCancel); + User::WaitForRequest(st); + BM_ERROR(st.Int(), st == KErrCancel); + TBMTicks t2; + ::bmTimer.Stamp(&t2); + aResult->Cumulate(TBMTicksDelta(t1, t2)); + CLOSE_AND_WAIT(child); + prog.EnableCleanup(); + } + } + +TInt Thread::KillingChild(TAny*) + { + User::WaitForAnyRequest(); + return KErrNone; + } + +#define TLS_KEY ((TInt32) &Thread::SetTls) + +void Thread::SetTls(TBMResult* aResult, TBMUInt64 aIter) + { + aIter <<= 4; + + TBMTimeInterval ti; + ti.Begin(); + for (TBMUInt64 i = 0; i < aIter; ++i) + { + TInt r = UserSvr::DllSetTls(TLS_KEY, 0); + BM_ERROR(r, r == KErrNone); + } + TBMTicks t = ti.End(); + aResult->Cumulate(t, aIter); + + UserSvr::DllFreeTls(TLS_KEY); + } + +void Thread::GetTls(TBMResult* aResult, TBMUInt64 aIter) + { + aIter <<= 4; + + TInt r = UserSvr::DllSetTls(TLS_KEY, 0); + BM_ERROR(r, r == KErrNone); + + TBMTimeInterval ti; + ti.Begin(); + for (TBMUInt64 i = 0; i < aIter; ++i) + { + UserSvr::DllTls(TLS_KEY); + } + TBMTicks t = ti.End(); + aResult->Cumulate(t, aIter); + + UserSvr::DllFreeTls(TLS_KEY); + } + +TBMResult* Thread::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); + iMeasurements[i].iFunc(&iResults[i], aIter); + iResults[i].Update(); + } + + *aCount = count; + return iResults; + } + +void AddThread() + { + BMProgram* next = bmSuite; + bmSuite=(BMProgram*)&prog; + bmSuite->Next()=next; + }