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