|
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 |