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