os/kernelhwsrv/kerneltest/e32test/benchmark/bm_suite.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #if !defined(__BM_SUITE_H__)
    17 #define __BM_SUITE_H__
    18 
    19 #include <e32test.h>
    20 
    21 #include "d32bm.h"
    22 
    23 /**
    24  * Gets access to the benchmark suite global log window/file.
    25  */
    26 extern RTest test;
    27 /**
    28  * Tests for an error condition.
    29  *
    30  * If the error condition is detected the macro prints out the file name, the line number and 
    31  * the error code, and aborts the benchmark suite.  
    32  *
    33  * @param aError an error number; printed out in the case if the error condition is detected.
    34  * @param aCond non-error condition: if 1 - no errors; if 0 - error. 
    35  */
    36 #define BM_ERROR(aError, aCond) \
    37 	__ASSERT_ALWAYS(aCond, bm_error_detected((TInt) aError, "'"#aCond"'", __FILE__, __LINE__))
    38 void bm_error_detected(TInt aError, char* aCond, char* aFile, TInt aLine);
    39 
    40 /**
    41  * Verify a condition
    42  *
    43  * If the value of condition is 0 prints out the file name, the line number and 
    44  * aborts the benchmark suite.
    45  *
    46  * @param aCond the condition that shell be verified.
    47  */
    48 
    49 #define BM_ASSERT(aCond) \
    50 	__ASSERT_DEBUG(aCond, bm_assert_failed("'"#aCond"'", __FILE__, __LINE__))
    51 void bm_assert_failed(char* aFile, char* aCond, TInt aLine);
    52 
    53 /**
    54  * An object of <code>TBMResult</code> class collects results of a measurement of a single perfrormance characteristic.
    55  * 
    56  * Objects of <code>TBMResult</code> class are typically reside in benchmark programs' static data
    57  * and returned as programs' results.
    58  */
    59 class TBMResult
    60 	{
    61 public:
    62 	/**
    63 	 * Constructs a non-initialized <code>TBMResult</code> object. 
    64 	 * Such a non-intialised object must be reset using void <code>TBMResult::Reset(const TDesC&)</code> function 
    65 	 * prior to be actually used.
    66 	 */
    67 	TBMResult()	{}
    68 	/**
    69 	 * Constructs a <code>TBMResult</code> object. 
    70 	 *
    71 	 * @param aName the measurement tite.
    72 	 */
    73 	TBMResult(const TDesC& aName); 
    74 	/**
    75 	 * Resets an existing <code>TBMResult</code> object. 
    76 	 * Sets the object in exactly the same state as <code>TBMResult::TBMResult(const TDesC&)</code>.
    77 	 *
    78 	 * @param aName the measurement tite.
    79 	 */ 
    80 	void Reset(const TDesC& aName);
    81 	/**
    82 	 * Stores the result of a new iteration.
    83 	 *
    84 	 * @param aTicks the iteration's elapsed time in ticks.
    85 	 */
    86 	void Cumulate(TBMTicks aTicks);
    87 	/**
    88 	 * Stores the cumulated result of a number of iterations.
    89 	 *
    90 	 * @param aTicks the cumulated elapsed time
    91 	 * @param aIter the number of iterations.
    92 	 */
    93 	void Cumulate(TBMTicks aTicks, TBMUInt64 aIter);
    94 	/**
    95 	 * Calculate <code>TBMResult::iMin, TBMResult::iMax, TBMResult::iAverage</code> in nano-seconds
    96 	 */
    97 	void Update();
    98 	/**
    99 	 * The title of the performance measurement
   100 	 */
   101 	TPtrC	iName;
   102 	/**
   103 	 * The number of iteration has been performed
   104 	 */
   105 	TBMUInt64	iIterations;
   106 	/**
   107 	 * The minimal elapsed time in nano-seconds.
   108 	 */
   109 	TBMNs	iMin;
   110 	/**
   111 	 * The maximal elapsed time in nano-seconds
   112 	 */ 
   113 	TBMNs	iMax;
   114 	/**
   115 	 * The average elapsed time in nano-seconds.
   116 	 */
   117 	TBMNs	iAverage;
   118 
   119 	enum
   120 		{ 	
   121 		/**
   122 		 * The size of the buffer for the results of leading iterations
   123 		 */
   124 		KHeadSize = 4
   125 		};
   126 	enum
   127 		{
   128 		/**
   129 		 * The size of the buffer for the results of tailing iterations
   130 		 */
   131 		KTailSize = 4 
   132 		};
   133 	/**
   134 	 * The buffer with the results of <code>KHeadSize</code> leading iterations.
   135 	 */
   136 	TBMNs	iHead[KHeadSize];
   137 	/**
   138 	 * The buffer with the results of <code>KTailSize</code> trailing iterations.
   139 	 */
   140 	TBMNs	iTail[KTailSize];
   141 
   142 // private:
   143 
   144 	void Reset();
   145 	
   146 	TBMTicks	iMinTicks;				// the minimal elapsed time in ticks
   147 	TBMTicks	iMaxTicks;				// the maximal elapsed time in ticks
   148 	TBMTicks	iCumulatedTicks;		// the elapsed time in ticks cumulated over iCumulatedIterations
   149 	TBMUInt64	iCumulatedIterations;	// the number of iterations for iCumulatedTicks
   150 
   151 	TBMTicks	iHeadTicks[KHeadSize];	// the first KHeadSize results in ticks
   152 	TBMTicks	iTailTicks[KTailSize];	// the last KTailSize results in ticks
   153 	};
   154 
   155 /**
   156  * An object of <code>TBMTimeInterval</code> can be used to measure potentially very long time interval.
   157  * 
   158  * If the measured time interval is shorter than the period of <code>RBMTimer</code> 
   159  * this high-precision timer will be used; otherwise, <code>TTime</code> timer will be used.
   160  */
   161 class TBMTimeInterval
   162 	{
   163 public:
   164 	/**
   165 	 * A static function to initialize the class static state. 
   166 	 * Called once by the benchmark suite launcher.
   167 	 */
   168 	static void Init();
   169 	/**
   170 	 * Begins the time interval measurement.
   171 	 */
   172 	void Begin();
   173 	/**
   174 	 * Ends the time interval measurement.
   175 	 *
   176 	 * @return the elapsed time in nano-seconds
   177 	 */
   178 	TBMNs EndNs();
   179 	/**
   180 	 * Ends the time interval measurement.
   181 	 *
   182 	 * @return the elapsed time in <code>RBMTimer</code> ticks. 
   183 	 *		Note that the time is always returned in <code>RBMTimer</code> ticks regardless which of two timers,
   184 	 *		<code>TTime</code> or <code>RBMTimer</code>, was actually used.
   185 	 */
   186 	TBMTicks End();
   187 
   188 	/**
   189 	 * Period of RBMTimer in nano-seconds
   190 	 */
   191 	static TBMNs	iStampPeriodNs;
   192 	/**
   193 	 * Period of RBMTimer in ticks
   194 	 */
   195 	static TBMTicks	iStampPeriod;
   196 
   197 private:
   198 
   199 	TBMTicks	iStamp;				// the starting time in RBMTimer ticks
   200 	TTime		iTime;				// the starting TTime
   201 	};
   202 
   203 
   204 /**
   205  * Calculates elapsed time in ticks taking care about possible timer overflow.
   206  *
   207  * @param aT0 the beginning of the measured interval
   208  * @param aT1 the end of the measured interval.
   209  * 
   210  */
   211 inline TBMTicks TBMTicksDelta(TBMTicks aT0, TBMTicks aT1)
   212 	{
   213 	return (aT0 <= aT1) ? (aT1 - aT0) : TBMTimeInterval::iStampPeriod - (aT0 - aT1);
   214 	}
   215 
   216 
   217 /**
   218  * Absolute thread prioiries to be used by benchmark programs
   219  */
   220 enum 
   221 	{
   222 	/**
   223 	 * Absolute priority to be used for high-priority threads.
   224 	 * 
   225 	 */
   226 	KBMPriorityHigh = 60, // 60 is above all DFC 26 is below timer DFC
   227 	/**
   228 	 * Absolute priority to be used for middle-priority threads.
   229 	 * This is also the default prioirty - performance benchmarks are started at this prioirty.
   230 	 */	
   231 	KBMPriorityMid = KBMPriorityHigh - 1,
   232 	/**
   233 	 * Absolute priority to be used for low-priority threads.
   234 	 */
   235 	KBMPriorityLow = KBMPriorityMid - 1
   236 	};
   237 
   238 
   239 /**
   240  * An object of <code>TBMSpawnArgs</code> type is used to pass arguments through 
   241  * <code>BMProgram::SpawnChild()</code> function from a parent to a child thread.
   242  *
   243  * <code>TBMSpawnArgs</code> is typically used as the base class for the actual argument passing object 
   244  * which may define some additional benchmark program specific arguments. 
   245  * The command line descriptor is used to pass a copy of the whole <code>TBMSpawnArgs</code> object 
   246  * from the parent process to the child one.
   247  */
   248 struct TBMSpawnArgs
   249 	{
   250 	/**
   251 	 * A magic value to allow the child recognize a command line as a <code>TBMSpawnArgs</code> object.
   252 	 * Intialized by constructor.
   253 	 */
   254 	TInt			iMagic;
   255 	/**
   256 	 * A handle to the parent thread. 
   257 	 * Intialized by constructor.
   258 	 */
   259 	RThread			iParent;
   260 	/**
   261 	 * The id of the parent thread.
   262 	 * Intialized by constructor.
   263 	 */
   264 	TThreadId		iParentId;
   265 	/**
   266 	 * If <code>ETrue</code> the child thread runs in a separate process; 
   267 	 * otherwise, the child thread runs within the parent's process.
   268 	 * Intialized by constructor.
   269 	 */
   270 	TBool			iRemote;
   271 	/**
   272 	 * The child entry point.
   273 	 * Intialized by constructor.
   274 	 */
   275 	TThreadFunction iChildFunc;
   276 	/**
   277 	 * The child thread absolute prioirty.
   278 	 * Intialized by constructor.
   279 	 */
   280 	TInt			iChildPrio;
   281 
   282 	TInt			iChildOrigPriority;
   283 	/**
   284 	 * The actual size of the <code>TBMSpawnArgs</code> object.
   285 	 * Intialized by constructor.
   286 	 */
   287 	TInt			iSize;
   288 	/**
   289 	 * The TBMSpawnArgs magic value.
   290 	 */
   291 	static const TInt KMagic;
   292 	/**
   293 	 * Construct a new <code>TBMSpawnArgs</code> object.
   294 	 *
   295 	 * @param aChildFunc the child entry point
   296 	 * @param aChildPrio the child thread absolute prioirty
   297 	 * @param aRemote if <code>ETrue</code> the child thread must be created in a separate process; 
   298 	 *		otherwise, the child thread must be created within the parent's process.
   299 	 */
   300 	TBMSpawnArgs(TThreadFunction aChildFunc, TInt aChildPrio, TBool aRemote, TInt aSize);
   301 	/**
   302 	 * Releases all allocated resources e.g. (<code>iParent</code> handle)
   303 	 */
   304 	~TBMSpawnArgs();
   305 	};
   306 
   307 /**
   308  * Child thread interface. Returned by <code>BMProgram::SpawnChild()</code>
   309  */
   310 class MBMChild
   311 	{
   312 public:
   313 	/**
   314 	 * Wait for the actual child thread termination.
   315 	 */
   316 	virtual void WaitChildExit() = 0;
   317 	/**
   318 	 * Requests the child thread termination.
   319 	 */
   320 	virtual void Kill() = 0;
   321 	};
   322 
   323 /**
   324  * A benchmark program is implemented as a sub-class of the abstract <code>BMProgram</code> class.
   325  * 
   326  * A typical benchmark program implements <code>BMProgram::Run()</code> pure virtual function and 
   327  * instantiate an object of the implemented sub-class in its static data.
   328  */
   329 class BMProgram 
   330 	{
   331 private:
   332 
   333 	BMProgram*	iNext;
   334 	TPtrC		iName;
   335 
   336 	MBMChild* SpawnLocalChild(TBMSpawnArgs*);
   337 	MBMChild* SpawnRemoteChild(TBMSpawnArgs*);
   338 	
   339 public:
   340 
   341 	/**
   342 	 * Utility function to change a thread's absolute priority.
   343 	 * 
   344 	 * @param aThread a handle ro the target thread.
   345 	 * @param aNewPrio a new absolute priority for the target thread
   346 	 * @return the old absolute prioirty of the target thread 
   347 	 */
   348 	static TInt SetAbsPriority(RThread aThread, TInt aNewPrio);	
   349 	
   350 	/**
   351 	 * Constructs a new <code>BMProgram</code> object.
   352 	 *
   353 	 * @param aName the bechmark program's title
   354 	 */
   355 	BMProgram(const TDesC& aName) : iName(aName)
   356 		{}
   357 
   358 	/**
   359 	 * Gets the nest program in the banchmark suite
   360 	 *
   361 	 * @return a pointer to the <code>BMProgram</code> object corresponding to the next benchmark program
   362 	 *		in the benchmark suite
   363 	 */
   364 	BMProgram*& Next()
   365 		{
   366 		return iNext;
   367 		}
   368 	/**
   369 	 * Gets the benchmark program title
   370 	 * 
   371 	 * @return a refernce to the descriptor containing the benchmark program title.
   372 	 */
   373 	const TDesC& Name()
   374 		{
   375 		return iName;
   376 		}
   377 	/**
   378 	 * Runs the benchmark program.
   379 	 *
   380 	 * @param aIter the required number of iterations
   381 	 * @retval aCount the number of performance characteristics measured by the benchmark program.
   382 	 * @return a pointer to an array of <code>TBMResult</code> objects with the results of measurements of
   383 	 *		individual performance characteristics. The number of array's elements is returned as 
   384 	 *		aCount argument.
   385 	 */
   386 	virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount) = 0;
   387 
   388 	/**
   389 	 * Spawn a child thread
   390 	 * 
   391 	 * @param args a pointer to a <code>TBMSpawnArgs</code> object that contains genric spawn operation parameters
   392 	 *		as well as program specific arguments to be passed to the chile thread.
   393 	 */
   394 	MBMChild* SpawnChild(TBMSpawnArgs* args);
   395 
   396 	/**
   397 	 * The main benchmark thread's absolute priority as was assigned by the loader. 
   398 	 */
   399 	TInt	iOrigAbsPriority;
   400 	};
   401 
   402 /**
   403  * The benchmark suite wide handle to the high-precision <code>RBMTimer</code>.
   404  */
   405 extern RBMTimer bmTimer;
   406 extern BMProgram* bmSuite;
   407 
   408 void AddrtLatency();
   409 void AddOverhead();
   410 void AddSync();
   411 void AddIpc();
   412 void AddThread();
   413 void AddProperty();
   414 
   415 
   416 #endif