1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/benchmark/bm_suite.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,416 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#if !defined(__BM_SUITE_H__)
1.20 +#define __BM_SUITE_H__
1.21 +
1.22 +#include <e32test.h>
1.23 +
1.24 +#include "d32bm.h"
1.25 +
1.26 +/**
1.27 + * Gets access to the benchmark suite global log window/file.
1.28 + */
1.29 +extern RTest test;
1.30 +/**
1.31 + * Tests for an error condition.
1.32 + *
1.33 + * If the error condition is detected the macro prints out the file name, the line number and
1.34 + * the error code, and aborts the benchmark suite.
1.35 + *
1.36 + * @param aError an error number; printed out in the case if the error condition is detected.
1.37 + * @param aCond non-error condition: if 1 - no errors; if 0 - error.
1.38 + */
1.39 +#define BM_ERROR(aError, aCond) \
1.40 + __ASSERT_ALWAYS(aCond, bm_error_detected((TInt) aError, "'"#aCond"'", __FILE__, __LINE__))
1.41 +void bm_error_detected(TInt aError, char* aCond, char* aFile, TInt aLine);
1.42 +
1.43 +/**
1.44 + * Verify a condition
1.45 + *
1.46 + * If the value of condition is 0 prints out the file name, the line number and
1.47 + * aborts the benchmark suite.
1.48 + *
1.49 + * @param aCond the condition that shell be verified.
1.50 + */
1.51 +
1.52 +#define BM_ASSERT(aCond) \
1.53 + __ASSERT_DEBUG(aCond, bm_assert_failed("'"#aCond"'", __FILE__, __LINE__))
1.54 +void bm_assert_failed(char* aFile, char* aCond, TInt aLine);
1.55 +
1.56 +/**
1.57 + * An object of <code>TBMResult</code> class collects results of a measurement of a single perfrormance characteristic.
1.58 + *
1.59 + * Objects of <code>TBMResult</code> class are typically reside in benchmark programs' static data
1.60 + * and returned as programs' results.
1.61 + */
1.62 +class TBMResult
1.63 + {
1.64 +public:
1.65 + /**
1.66 + * Constructs a non-initialized <code>TBMResult</code> object.
1.67 + * Such a non-intialised object must be reset using void <code>TBMResult::Reset(const TDesC&)</code> function
1.68 + * prior to be actually used.
1.69 + */
1.70 + TBMResult() {}
1.71 + /**
1.72 + * Constructs a <code>TBMResult</code> object.
1.73 + *
1.74 + * @param aName the measurement tite.
1.75 + */
1.76 + TBMResult(const TDesC& aName);
1.77 + /**
1.78 + * Resets an existing <code>TBMResult</code> object.
1.79 + * Sets the object in exactly the same state as <code>TBMResult::TBMResult(const TDesC&)</code>.
1.80 + *
1.81 + * @param aName the measurement tite.
1.82 + */
1.83 + void Reset(const TDesC& aName);
1.84 + /**
1.85 + * Stores the result of a new iteration.
1.86 + *
1.87 + * @param aTicks the iteration's elapsed time in ticks.
1.88 + */
1.89 + void Cumulate(TBMTicks aTicks);
1.90 + /**
1.91 + * Stores the cumulated result of a number of iterations.
1.92 + *
1.93 + * @param aTicks the cumulated elapsed time
1.94 + * @param aIter the number of iterations.
1.95 + */
1.96 + void Cumulate(TBMTicks aTicks, TBMUInt64 aIter);
1.97 + /**
1.98 + * Calculate <code>TBMResult::iMin, TBMResult::iMax, TBMResult::iAverage</code> in nano-seconds
1.99 + */
1.100 + void Update();
1.101 + /**
1.102 + * The title of the performance measurement
1.103 + */
1.104 + TPtrC iName;
1.105 + /**
1.106 + * The number of iteration has been performed
1.107 + */
1.108 + TBMUInt64 iIterations;
1.109 + /**
1.110 + * The minimal elapsed time in nano-seconds.
1.111 + */
1.112 + TBMNs iMin;
1.113 + /**
1.114 + * The maximal elapsed time in nano-seconds
1.115 + */
1.116 + TBMNs iMax;
1.117 + /**
1.118 + * The average elapsed time in nano-seconds.
1.119 + */
1.120 + TBMNs iAverage;
1.121 +
1.122 + enum
1.123 + {
1.124 + /**
1.125 + * The size of the buffer for the results of leading iterations
1.126 + */
1.127 + KHeadSize = 4
1.128 + };
1.129 + enum
1.130 + {
1.131 + /**
1.132 + * The size of the buffer for the results of tailing iterations
1.133 + */
1.134 + KTailSize = 4
1.135 + };
1.136 + /**
1.137 + * The buffer with the results of <code>KHeadSize</code> leading iterations.
1.138 + */
1.139 + TBMNs iHead[KHeadSize];
1.140 + /**
1.141 + * The buffer with the results of <code>KTailSize</code> trailing iterations.
1.142 + */
1.143 + TBMNs iTail[KTailSize];
1.144 +
1.145 +// private:
1.146 +
1.147 + void Reset();
1.148 +
1.149 + TBMTicks iMinTicks; // the minimal elapsed time in ticks
1.150 + TBMTicks iMaxTicks; // the maximal elapsed time in ticks
1.151 + TBMTicks iCumulatedTicks; // the elapsed time in ticks cumulated over iCumulatedIterations
1.152 + TBMUInt64 iCumulatedIterations; // the number of iterations for iCumulatedTicks
1.153 +
1.154 + TBMTicks iHeadTicks[KHeadSize]; // the first KHeadSize results in ticks
1.155 + TBMTicks iTailTicks[KTailSize]; // the last KTailSize results in ticks
1.156 + };
1.157 +
1.158 +/**
1.159 + * An object of <code>TBMTimeInterval</code> can be used to measure potentially very long time interval.
1.160 + *
1.161 + * If the measured time interval is shorter than the period of <code>RBMTimer</code>
1.162 + * this high-precision timer will be used; otherwise, <code>TTime</code> timer will be used.
1.163 + */
1.164 +class TBMTimeInterval
1.165 + {
1.166 +public:
1.167 + /**
1.168 + * A static function to initialize the class static state.
1.169 + * Called once by the benchmark suite launcher.
1.170 + */
1.171 + static void Init();
1.172 + /**
1.173 + * Begins the time interval measurement.
1.174 + */
1.175 + void Begin();
1.176 + /**
1.177 + * Ends the time interval measurement.
1.178 + *
1.179 + * @return the elapsed time in nano-seconds
1.180 + */
1.181 + TBMNs EndNs();
1.182 + /**
1.183 + * Ends the time interval measurement.
1.184 + *
1.185 + * @return the elapsed time in <code>RBMTimer</code> ticks.
1.186 + * Note that the time is always returned in <code>RBMTimer</code> ticks regardless which of two timers,
1.187 + * <code>TTime</code> or <code>RBMTimer</code>, was actually used.
1.188 + */
1.189 + TBMTicks End();
1.190 +
1.191 + /**
1.192 + * Period of RBMTimer in nano-seconds
1.193 + */
1.194 + static TBMNs iStampPeriodNs;
1.195 + /**
1.196 + * Period of RBMTimer in ticks
1.197 + */
1.198 + static TBMTicks iStampPeriod;
1.199 +
1.200 +private:
1.201 +
1.202 + TBMTicks iStamp; // the starting time in RBMTimer ticks
1.203 + TTime iTime; // the starting TTime
1.204 + };
1.205 +
1.206 +
1.207 +/**
1.208 + * Calculates elapsed time in ticks taking care about possible timer overflow.
1.209 + *
1.210 + * @param aT0 the beginning of the measured interval
1.211 + * @param aT1 the end of the measured interval.
1.212 + *
1.213 + */
1.214 +inline TBMTicks TBMTicksDelta(TBMTicks aT0, TBMTicks aT1)
1.215 + {
1.216 + return (aT0 <= aT1) ? (aT1 - aT0) : TBMTimeInterval::iStampPeriod - (aT0 - aT1);
1.217 + }
1.218 +
1.219 +
1.220 +/**
1.221 + * Absolute thread prioiries to be used by benchmark programs
1.222 + */
1.223 +enum
1.224 + {
1.225 + /**
1.226 + * Absolute priority to be used for high-priority threads.
1.227 + *
1.228 + */
1.229 + KBMPriorityHigh = 60, // 60 is above all DFC 26 is below timer DFC
1.230 + /**
1.231 + * Absolute priority to be used for middle-priority threads.
1.232 + * This is also the default prioirty - performance benchmarks are started at this prioirty.
1.233 + */
1.234 + KBMPriorityMid = KBMPriorityHigh - 1,
1.235 + /**
1.236 + * Absolute priority to be used for low-priority threads.
1.237 + */
1.238 + KBMPriorityLow = KBMPriorityMid - 1
1.239 + };
1.240 +
1.241 +
1.242 +/**
1.243 + * An object of <code>TBMSpawnArgs</code> type is used to pass arguments through
1.244 + * <code>BMProgram::SpawnChild()</code> function from a parent to a child thread.
1.245 + *
1.246 + * <code>TBMSpawnArgs</code> is typically used as the base class for the actual argument passing object
1.247 + * which may define some additional benchmark program specific arguments.
1.248 + * The command line descriptor is used to pass a copy of the whole <code>TBMSpawnArgs</code> object
1.249 + * from the parent process to the child one.
1.250 + */
1.251 +struct TBMSpawnArgs
1.252 + {
1.253 + /**
1.254 + * A magic value to allow the child recognize a command line as a <code>TBMSpawnArgs</code> object.
1.255 + * Intialized by constructor.
1.256 + */
1.257 + TInt iMagic;
1.258 + /**
1.259 + * A handle to the parent thread.
1.260 + * Intialized by constructor.
1.261 + */
1.262 + RThread iParent;
1.263 + /**
1.264 + * The id of the parent thread.
1.265 + * Intialized by constructor.
1.266 + */
1.267 + TThreadId iParentId;
1.268 + /**
1.269 + * If <code>ETrue</code> the child thread runs in a separate process;
1.270 + * otherwise, the child thread runs within the parent's process.
1.271 + * Intialized by constructor.
1.272 + */
1.273 + TBool iRemote;
1.274 + /**
1.275 + * The child entry point.
1.276 + * Intialized by constructor.
1.277 + */
1.278 + TThreadFunction iChildFunc;
1.279 + /**
1.280 + * The child thread absolute prioirty.
1.281 + * Intialized by constructor.
1.282 + */
1.283 + TInt iChildPrio;
1.284 +
1.285 + TInt iChildOrigPriority;
1.286 + /**
1.287 + * The actual size of the <code>TBMSpawnArgs</code> object.
1.288 + * Intialized by constructor.
1.289 + */
1.290 + TInt iSize;
1.291 + /**
1.292 + * The TBMSpawnArgs magic value.
1.293 + */
1.294 + static const TInt KMagic;
1.295 + /**
1.296 + * Construct a new <code>TBMSpawnArgs</code> object.
1.297 + *
1.298 + * @param aChildFunc the child entry point
1.299 + * @param aChildPrio the child thread absolute prioirty
1.300 + * @param aRemote if <code>ETrue</code> the child thread must be created in a separate process;
1.301 + * otherwise, the child thread must be created within the parent's process.
1.302 + */
1.303 + TBMSpawnArgs(TThreadFunction aChildFunc, TInt aChildPrio, TBool aRemote, TInt aSize);
1.304 + /**
1.305 + * Releases all allocated resources e.g. (<code>iParent</code> handle)
1.306 + */
1.307 + ~TBMSpawnArgs();
1.308 + };
1.309 +
1.310 +/**
1.311 + * Child thread interface. Returned by <code>BMProgram::SpawnChild()</code>
1.312 + */
1.313 +class MBMChild
1.314 + {
1.315 +public:
1.316 + /**
1.317 + * Wait for the actual child thread termination.
1.318 + */
1.319 + virtual void WaitChildExit() = 0;
1.320 + /**
1.321 + * Requests the child thread termination.
1.322 + */
1.323 + virtual void Kill() = 0;
1.324 + };
1.325 +
1.326 +/**
1.327 + * A benchmark program is implemented as a sub-class of the abstract <code>BMProgram</code> class.
1.328 + *
1.329 + * A typical benchmark program implements <code>BMProgram::Run()</code> pure virtual function and
1.330 + * instantiate an object of the implemented sub-class in its static data.
1.331 + */
1.332 +class BMProgram
1.333 + {
1.334 +private:
1.335 +
1.336 + BMProgram* iNext;
1.337 + TPtrC iName;
1.338 +
1.339 + MBMChild* SpawnLocalChild(TBMSpawnArgs*);
1.340 + MBMChild* SpawnRemoteChild(TBMSpawnArgs*);
1.341 +
1.342 +public:
1.343 +
1.344 + /**
1.345 + * Utility function to change a thread's absolute priority.
1.346 + *
1.347 + * @param aThread a handle ro the target thread.
1.348 + * @param aNewPrio a new absolute priority for the target thread
1.349 + * @return the old absolute prioirty of the target thread
1.350 + */
1.351 + static TInt SetAbsPriority(RThread aThread, TInt aNewPrio);
1.352 +
1.353 + /**
1.354 + * Constructs a new <code>BMProgram</code> object.
1.355 + *
1.356 + * @param aName the bechmark program's title
1.357 + */
1.358 + BMProgram(const TDesC& aName) : iName(aName)
1.359 + {}
1.360 +
1.361 + /**
1.362 + * Gets the nest program in the banchmark suite
1.363 + *
1.364 + * @return a pointer to the <code>BMProgram</code> object corresponding to the next benchmark program
1.365 + * in the benchmark suite
1.366 + */
1.367 + BMProgram*& Next()
1.368 + {
1.369 + return iNext;
1.370 + }
1.371 + /**
1.372 + * Gets the benchmark program title
1.373 + *
1.374 + * @return a refernce to the descriptor containing the benchmark program title.
1.375 + */
1.376 + const TDesC& Name()
1.377 + {
1.378 + return iName;
1.379 + }
1.380 + /**
1.381 + * Runs the benchmark program.
1.382 + *
1.383 + * @param aIter the required number of iterations
1.384 + * @retval aCount the number of performance characteristics measured by the benchmark program.
1.385 + * @return a pointer to an array of <code>TBMResult</code> objects with the results of measurements of
1.386 + * individual performance characteristics. The number of array's elements is returned as
1.387 + * aCount argument.
1.388 + */
1.389 + virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount) = 0;
1.390 +
1.391 + /**
1.392 + * Spawn a child thread
1.393 + *
1.394 + * @param args a pointer to a <code>TBMSpawnArgs</code> object that contains genric spawn operation parameters
1.395 + * as well as program specific arguments to be passed to the chile thread.
1.396 + */
1.397 + MBMChild* SpawnChild(TBMSpawnArgs* args);
1.398 +
1.399 + /**
1.400 + * The main benchmark thread's absolute priority as was assigned by the loader.
1.401 + */
1.402 + TInt iOrigAbsPriority;
1.403 + };
1.404 +
1.405 +/**
1.406 + * The benchmark suite wide handle to the high-precision <code>RBMTimer</code>.
1.407 + */
1.408 +extern RBMTimer bmTimer;
1.409 +extern BMProgram* bmSuite;
1.410 +
1.411 +void AddrtLatency();
1.412 +void AddOverhead();
1.413 +void AddSync();
1.414 +void AddIpc();
1.415 +void AddThread();
1.416 +void AddProperty();
1.417 +
1.418 +
1.419 +#endif