kerneltest/e32test/benchmark/bm_suite.h
changeset 0 a41df078684a
child 39 2bb754abd467
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/benchmark/bm_suite.h	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,416 @@
+// 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