sl@0: // Copyright (c) 2002-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: // sl@0: sl@0: #if !defined(__BM_SUITE_H__) sl@0: #define __BM_SUITE_H__ sl@0: sl@0: #include sl@0: sl@0: #include "d32bm.h" sl@0: sl@0: /** sl@0: * Gets access to the benchmark suite global log window/file. sl@0: */ sl@0: extern RTest test; sl@0: /** sl@0: * Tests for an error condition. sl@0: * sl@0: * If the error condition is detected the macro prints out the file name, the line number and sl@0: * the error code, and aborts the benchmark suite. sl@0: * sl@0: * @param aError an error number; printed out in the case if the error condition is detected. sl@0: * @param aCond non-error condition: if 1 - no errors; if 0 - error. sl@0: */ sl@0: #define BM_ERROR(aError, aCond) \ sl@0: __ASSERT_ALWAYS(aCond, bm_error_detected((TInt) aError, "'"#aCond"'", __FILE__, __LINE__)) sl@0: void bm_error_detected(TInt aError, char* aCond, char* aFile, TInt aLine); sl@0: sl@0: /** sl@0: * Verify a condition sl@0: * sl@0: * If the value of condition is 0 prints out the file name, the line number and sl@0: * aborts the benchmark suite. sl@0: * sl@0: * @param aCond the condition that shell be verified. sl@0: */ sl@0: sl@0: #define BM_ASSERT(aCond) \ sl@0: __ASSERT_DEBUG(aCond, bm_assert_failed("'"#aCond"'", __FILE__, __LINE__)) sl@0: void bm_assert_failed(char* aFile, char* aCond, TInt aLine); sl@0: sl@0: /** sl@0: * An object of TBMResult class collects results of a measurement of a single perfrormance characteristic. sl@0: * sl@0: * Objects of TBMResult class are typically reside in benchmark programs' static data sl@0: * and returned as programs' results. sl@0: */ sl@0: class TBMResult sl@0: { sl@0: public: sl@0: /** sl@0: * Constructs a non-initialized TBMResult object. sl@0: * Such a non-intialised object must be reset using void TBMResult::Reset(const TDesC&) function sl@0: * prior to be actually used. sl@0: */ sl@0: TBMResult() {} sl@0: /** sl@0: * Constructs a TBMResult object. sl@0: * sl@0: * @param aName the measurement tite. sl@0: */ sl@0: TBMResult(const TDesC& aName); sl@0: /** sl@0: * Resets an existing TBMResult object. sl@0: * Sets the object in exactly the same state as TBMResult::TBMResult(const TDesC&). sl@0: * sl@0: * @param aName the measurement tite. sl@0: */ sl@0: void Reset(const TDesC& aName); sl@0: /** sl@0: * Stores the result of a new iteration. sl@0: * sl@0: * @param aTicks the iteration's elapsed time in ticks. sl@0: */ sl@0: void Cumulate(TBMTicks aTicks); sl@0: /** sl@0: * Stores the cumulated result of a number of iterations. sl@0: * sl@0: * @param aTicks the cumulated elapsed time sl@0: * @param aIter the number of iterations. sl@0: */ sl@0: void Cumulate(TBMTicks aTicks, TBMUInt64 aIter); sl@0: /** sl@0: * Calculate TBMResult::iMin, TBMResult::iMax, TBMResult::iAverage in nano-seconds sl@0: */ sl@0: void Update(); sl@0: /** sl@0: * The title of the performance measurement sl@0: */ sl@0: TPtrC iName; sl@0: /** sl@0: * The number of iteration has been performed sl@0: */ sl@0: TBMUInt64 iIterations; sl@0: /** sl@0: * The minimal elapsed time in nano-seconds. sl@0: */ sl@0: TBMNs iMin; sl@0: /** sl@0: * The maximal elapsed time in nano-seconds sl@0: */ sl@0: TBMNs iMax; sl@0: /** sl@0: * The average elapsed time in nano-seconds. sl@0: */ sl@0: TBMNs iAverage; sl@0: sl@0: enum sl@0: { sl@0: /** sl@0: * The size of the buffer for the results of leading iterations sl@0: */ sl@0: KHeadSize = 4 sl@0: }; sl@0: enum sl@0: { sl@0: /** sl@0: * The size of the buffer for the results of tailing iterations sl@0: */ sl@0: KTailSize = 4 sl@0: }; sl@0: /** sl@0: * The buffer with the results of KHeadSize leading iterations. sl@0: */ sl@0: TBMNs iHead[KHeadSize]; sl@0: /** sl@0: * The buffer with the results of KTailSize trailing iterations. sl@0: */ sl@0: TBMNs iTail[KTailSize]; sl@0: sl@0: // private: sl@0: sl@0: void Reset(); sl@0: sl@0: TBMTicks iMinTicks; // the minimal elapsed time in ticks sl@0: TBMTicks iMaxTicks; // the maximal elapsed time in ticks sl@0: TBMTicks iCumulatedTicks; // the elapsed time in ticks cumulated over iCumulatedIterations sl@0: TBMUInt64 iCumulatedIterations; // the number of iterations for iCumulatedTicks sl@0: sl@0: TBMTicks iHeadTicks[KHeadSize]; // the first KHeadSize results in ticks sl@0: TBMTicks iTailTicks[KTailSize]; // the last KTailSize results in ticks sl@0: }; sl@0: sl@0: /** sl@0: * An object of TBMTimeInterval can be used to measure potentially very long time interval. sl@0: * sl@0: * If the measured time interval is shorter than the period of RBMTimer sl@0: * this high-precision timer will be used; otherwise, TTime timer will be used. sl@0: */ sl@0: class TBMTimeInterval sl@0: { sl@0: public: sl@0: /** sl@0: * A static function to initialize the class static state. sl@0: * Called once by the benchmark suite launcher. sl@0: */ sl@0: static void Init(); sl@0: /** sl@0: * Begins the time interval measurement. sl@0: */ sl@0: void Begin(); sl@0: /** sl@0: * Ends the time interval measurement. sl@0: * sl@0: * @return the elapsed time in nano-seconds sl@0: */ sl@0: TBMNs EndNs(); sl@0: /** sl@0: * Ends the time interval measurement. sl@0: * sl@0: * @return the elapsed time in RBMTimer ticks. sl@0: * Note that the time is always returned in RBMTimer ticks regardless which of two timers, sl@0: * TTime or RBMTimer, was actually used. sl@0: */ sl@0: TBMTicks End(); sl@0: sl@0: /** sl@0: * Period of RBMTimer in nano-seconds sl@0: */ sl@0: static TBMNs iStampPeriodNs; sl@0: /** sl@0: * Period of RBMTimer in ticks sl@0: */ sl@0: static TBMTicks iStampPeriod; sl@0: sl@0: private: sl@0: sl@0: TBMTicks iStamp; // the starting time in RBMTimer ticks sl@0: TTime iTime; // the starting TTime sl@0: }; sl@0: sl@0: sl@0: /** sl@0: * Calculates elapsed time in ticks taking care about possible timer overflow. sl@0: * sl@0: * @param aT0 the beginning of the measured interval sl@0: * @param aT1 the end of the measured interval. sl@0: * sl@0: */ sl@0: inline TBMTicks TBMTicksDelta(TBMTicks aT0, TBMTicks aT1) sl@0: { sl@0: return (aT0 <= aT1) ? (aT1 - aT0) : TBMTimeInterval::iStampPeriod - (aT0 - aT1); sl@0: } sl@0: sl@0: sl@0: /** sl@0: * Absolute thread prioiries to be used by benchmark programs sl@0: */ sl@0: enum sl@0: { sl@0: /** sl@0: * Absolute priority to be used for high-priority threads. sl@0: * sl@0: */ sl@0: KBMPriorityHigh = 60, // 60 is above all DFC 26 is below timer DFC sl@0: /** sl@0: * Absolute priority to be used for middle-priority threads. sl@0: * This is also the default prioirty - performance benchmarks are started at this prioirty. sl@0: */ sl@0: KBMPriorityMid = KBMPriorityHigh - 1, sl@0: /** sl@0: * Absolute priority to be used for low-priority threads. sl@0: */ sl@0: KBMPriorityLow = KBMPriorityMid - 1 sl@0: }; sl@0: sl@0: sl@0: /** sl@0: * An object of TBMSpawnArgs type is used to pass arguments through sl@0: * BMProgram::SpawnChild() function from a parent to a child thread. sl@0: * sl@0: * TBMSpawnArgs is typically used as the base class for the actual argument passing object sl@0: * which may define some additional benchmark program specific arguments. sl@0: * The command line descriptor is used to pass a copy of the whole TBMSpawnArgs object sl@0: * from the parent process to the child one. sl@0: */ sl@0: struct TBMSpawnArgs sl@0: { sl@0: /** sl@0: * A magic value to allow the child recognize a command line as a TBMSpawnArgs object. sl@0: * Intialized by constructor. sl@0: */ sl@0: TInt iMagic; sl@0: /** sl@0: * A handle to the parent thread. sl@0: * Intialized by constructor. sl@0: */ sl@0: RThread iParent; sl@0: /** sl@0: * The id of the parent thread. sl@0: * Intialized by constructor. sl@0: */ sl@0: TThreadId iParentId; sl@0: /** sl@0: * If ETrue the child thread runs in a separate process; sl@0: * otherwise, the child thread runs within the parent's process. sl@0: * Intialized by constructor. sl@0: */ sl@0: TBool iRemote; sl@0: /** sl@0: * The child entry point. sl@0: * Intialized by constructor. sl@0: */ sl@0: TThreadFunction iChildFunc; sl@0: /** sl@0: * The child thread absolute prioirty. sl@0: * Intialized by constructor. sl@0: */ sl@0: TInt iChildPrio; sl@0: sl@0: TInt iChildOrigPriority; sl@0: /** sl@0: * The actual size of the TBMSpawnArgs object. sl@0: * Intialized by constructor. sl@0: */ sl@0: TInt iSize; sl@0: /** sl@0: * The TBMSpawnArgs magic value. sl@0: */ sl@0: static const TInt KMagic; sl@0: /** sl@0: * Construct a new TBMSpawnArgs object. sl@0: * sl@0: * @param aChildFunc the child entry point sl@0: * @param aChildPrio the child thread absolute prioirty sl@0: * @param aRemote if ETrue the child thread must be created in a separate process; sl@0: * otherwise, the child thread must be created within the parent's process. sl@0: */ sl@0: TBMSpawnArgs(TThreadFunction aChildFunc, TInt aChildPrio, TBool aRemote, TInt aSize); sl@0: /** sl@0: * Releases all allocated resources e.g. (iParent handle) sl@0: */ sl@0: ~TBMSpawnArgs(); sl@0: }; sl@0: sl@0: /** sl@0: * Child thread interface. Returned by BMProgram::SpawnChild() sl@0: */ sl@0: class MBMChild sl@0: { sl@0: public: sl@0: /** sl@0: * Wait for the actual child thread termination. sl@0: */ sl@0: virtual void WaitChildExit() = 0; sl@0: /** sl@0: * Requests the child thread termination. sl@0: */ sl@0: virtual void Kill() = 0; sl@0: }; sl@0: sl@0: /** sl@0: * A benchmark program is implemented as a sub-class of the abstract BMProgram class. sl@0: * sl@0: * A typical benchmark program implements BMProgram::Run() pure virtual function and sl@0: * instantiate an object of the implemented sub-class in its static data. sl@0: */ sl@0: class BMProgram sl@0: { sl@0: private: sl@0: sl@0: BMProgram* iNext; sl@0: TPtrC iName; sl@0: sl@0: MBMChild* SpawnLocalChild(TBMSpawnArgs*); sl@0: MBMChild* SpawnRemoteChild(TBMSpawnArgs*); sl@0: sl@0: public: sl@0: sl@0: /** sl@0: * Utility function to change a thread's absolute priority. sl@0: * sl@0: * @param aThread a handle ro the target thread. sl@0: * @param aNewPrio a new absolute priority for the target thread sl@0: * @return the old absolute prioirty of the target thread sl@0: */ sl@0: static TInt SetAbsPriority(RThread aThread, TInt aNewPrio); sl@0: sl@0: /** sl@0: * Constructs a new BMProgram object. sl@0: * sl@0: * @param aName the bechmark program's title sl@0: */ sl@0: BMProgram(const TDesC& aName) : iName(aName) sl@0: {} sl@0: sl@0: /** sl@0: * Gets the nest program in the banchmark suite sl@0: * sl@0: * @return a pointer to the BMProgram object corresponding to the next benchmark program sl@0: * in the benchmark suite sl@0: */ sl@0: BMProgram*& Next() sl@0: { sl@0: return iNext; sl@0: } sl@0: /** sl@0: * Gets the benchmark program title sl@0: * sl@0: * @return a refernce to the descriptor containing the benchmark program title. sl@0: */ sl@0: const TDesC& Name() sl@0: { sl@0: return iName; sl@0: } sl@0: /** sl@0: * Runs the benchmark program. sl@0: * sl@0: * @param aIter the required number of iterations sl@0: * @retval aCount the number of performance characteristics measured by the benchmark program. sl@0: * @return a pointer to an array of TBMResult objects with the results of measurements of sl@0: * individual performance characteristics. The number of array's elements is returned as sl@0: * aCount argument. sl@0: */ sl@0: virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount) = 0; sl@0: sl@0: /** sl@0: * Spawn a child thread sl@0: * sl@0: * @param args a pointer to a TBMSpawnArgs object that contains genric spawn operation parameters sl@0: * as well as program specific arguments to be passed to the chile thread. sl@0: */ sl@0: MBMChild* SpawnChild(TBMSpawnArgs* args); sl@0: sl@0: /** sl@0: * The main benchmark thread's absolute priority as was assigned by the loader. sl@0: */ sl@0: TInt iOrigAbsPriority; sl@0: }; sl@0: sl@0: /** sl@0: * The benchmark suite wide handle to the high-precision RBMTimer. sl@0: */ sl@0: extern RBMTimer bmTimer; sl@0: extern BMProgram* bmSuite; sl@0: sl@0: void AddrtLatency(); sl@0: void AddOverhead(); sl@0: void AddSync(); sl@0: void AddIpc(); sl@0: void AddThread(); sl@0: void AddProperty(); sl@0: sl@0: sl@0: #endif