|
1 // Copyright (c) 2005-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 "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 #include <ecom/ecom.h> |
|
17 #include <hal.h> |
|
18 #include "EComSessionAux.h" |
|
19 |
|
20 #ifdef __ECOM_SERVER_TESTABILITY__ |
|
21 |
|
22 /** |
|
23 @internalComponent |
|
24 A helper function to use SetGetParametersL to set the next |
|
25 state to be used by the ServerStartupManager of EComServer |
|
26 @param aState the next state to be used by the EComServer |
|
27 */ |
|
28 void ChangeStartupStateL(TInt aState) |
|
29 { |
|
30 TIpcArgs params = TIpcArgs(EChangeStartupState, aState); |
|
31 REComSession::SetGetParametersL(params); |
|
32 } |
|
33 |
|
34 /** |
|
35 @internalComponent |
|
36 A helper function to use SetGetParametersL to force EComServer |
|
37 to process the next state. |
|
38 */ |
|
39 void ProcessCurrentStartupStateL() |
|
40 { |
|
41 TIpcArgs params = TIpcArgs(EProcessStartupState); |
|
42 REComSession::SetGetParametersL(params); |
|
43 } |
|
44 |
|
45 /** |
|
46 @internalComponent |
|
47 A helper function to use SetGetParametersL to get the current |
|
48 startup state of EComServer |
|
49 @return current startup state of EComServer |
|
50 */ |
|
51 TInt GetCurrentStartupStateL() |
|
52 { |
|
53 TInt currentState = 0; |
|
54 TPckg<TInt> statePckg(currentState); |
|
55 TIpcArgs params = TIpcArgs(EGetStartupState, &statePckg); |
|
56 REComSession::SetGetParametersL(params); |
|
57 |
|
58 return currentState; |
|
59 } |
|
60 |
|
61 #endif |
|
62 |
|
63 #ifdef __ECOM_SERVER_PERFORMANCE__ |
|
64 |
|
65 //==================== For Startup State Time Results =================== |
|
66 /** Method used for TLinearOrder for TTimerResult arrays*/ |
|
67 TInt CompareTimerResults(const TStartupStateTimerResult& aTimerResult1, const TStartupStateTimerResult& aTimerResult2) |
|
68 { |
|
69 if(aTimerResult1.iState < aTimerResult2.iState) |
|
70 { |
|
71 return -1; |
|
72 } |
|
73 else if(aTimerResult1.iState > aTimerResult2.iState) |
|
74 { |
|
75 return 1; |
|
76 } |
|
77 |
|
78 return 0; |
|
79 } |
|
80 |
|
81 /** Method used for TIdentityRelation for TTimerResult arrays*/ |
|
82 TBool MatchOnState(const TStartupStateTimerResult& aKey, const TStartupStateTimerResult& aIndexItem) |
|
83 { |
|
84 return aIndexItem.iState == aKey.iState; |
|
85 } |
|
86 |
|
87 TInt RStartupStateTimerResults::FindTimerResult(TInt aState) |
|
88 { |
|
89 TIdentityRelation<TStartupStateTimerResult> identity(MatchOnState); |
|
90 TStartupStateTimerResult key; |
|
91 key.iState = aState; |
|
92 return iTimerResults.Find(key, identity); |
|
93 } |
|
94 |
|
95 /** |
|
96 Method that returns the idx of the timer result at requested state |
|
97 @param aTimerResults the sorted timer results array to search for the |
|
98 timer value |
|
99 @param aState the state of the requested timer result |
|
100 @return The index of the matching timer result KErrNotFound, if no |
|
101 matching object can be found |
|
102 */ |
|
103 TInt RStartupStateTimerResults::FindInOrderTimerResult(TInt aState) |
|
104 { |
|
105 TLinearOrder<TStartupStateTimerResult> compareFunc(CompareTimerResults); |
|
106 TStartupStateTimerResult key; |
|
107 key.iState = aState; |
|
108 return iTimerResults.FindInOrder(key, compareFunc); |
|
109 } |
|
110 |
|
111 /** |
|
112 @internalComponent |
|
113 A helper function to use SetGetParametersL to get the timer recordings |
|
114 for performance testing. If the specified aTimerIdx is beyond the boundaries |
|
115 of the recorded values then aTimerResult would return a value of 0 and aState |
|
116 would return a value of -1. |
|
117 @param aTimerIdx the index of the timer to use |
|
118 @param aTimerResult the timer readings |
|
119 @param aState the state of the server when timer was read (a zero indexed value) |
|
120 */ |
|
121 TInt RStartupStateTimerResults::GetTimerResult(TInt aTimerIdx, TUint32& aTimerResult, TInt& aState) |
|
122 { |
|
123 TInt returnedStatus; |
|
124 TStartupStateTimerEntry result; |
|
125 |
|
126 TPckg<TInt> statusPckg(returnedStatus); |
|
127 TPckg<TStartupStateTimerEntry> resultPckg(result); |
|
128 |
|
129 TIpcArgs params = TIpcArgs(EGetStartupStateTimerResult, aTimerIdx, &statusPckg, &resultPckg); |
|
130 TRAPD(err, REComSession::SetGetParametersL(params)); |
|
131 if (err != KErrNone) |
|
132 { |
|
133 return err; |
|
134 } |
|
135 |
|
136 aTimerResult = result.iTimerResult; |
|
137 aState = result.iState; |
|
138 |
|
139 return returnedStatus; |
|
140 } |
|
141 |
|
142 /** |
|
143 @internalComponent |
|
144 A helper function to use SetGetParametersL to get all of the timer recordings |
|
145 for performance testing. |
|
146 @param aTimerResults a reference to an array to store sorted timer results. |
|
147 */ |
|
148 void RStartupStateTimerResults::GetAllTimerResults() |
|
149 { |
|
150 TInt counter = 0; |
|
151 while(ETrue) |
|
152 { |
|
153 TUint32 time = 0; |
|
154 TInt state = -1; |
|
155 TReal realTime = 0.0; |
|
156 |
|
157 // get state start info |
|
158 TInt err = GetTimerResult(counter++, time, state); |
|
159 if(err || (time == 0 && state == -1)) |
|
160 { |
|
161 break; |
|
162 } |
|
163 |
|
164 realTime = FastCountToMilliseconds(time); |
|
165 |
|
166 //search state |
|
167 TInt idx = FindTimerResult(state); |
|
168 if(idx == KErrNotFound) //if it has not been entered to the array make a new entry |
|
169 { |
|
170 TStartupStateTimerResult timerResult; |
|
171 timerResult.iState = state; |
|
172 timerResult.iStartTime = realTime; |
|
173 timerResult.iEndTime = 0; |
|
174 |
|
175 iTimerResults.Append(timerResult); |
|
176 } |
|
177 else //if it has already been entered update the end time |
|
178 { |
|
179 TStartupStateTimerResult& timerResult = iTimerResults[idx]; |
|
180 timerResult.iEndTime = realTime; |
|
181 } |
|
182 } |
|
183 |
|
184 //the array is populated, sort it for faster search. |
|
185 TLinearOrder<TStartupStateTimerResult> compareFunc(CompareTimerResults); |
|
186 iTimerResults.Sort(compareFunc); |
|
187 } |
|
188 |
|
189 void RStartupStateTimerResults::ResetTimerCountL() |
|
190 { |
|
191 |
|
192 TIpcArgs params = TIpcArgs(EResetStartupStateTimerCounts); |
|
193 REComSession::SetGetParametersL(params); |
|
194 } |
|
195 |
|
196 /** |
|
197 Frees any allocated resources |
|
198 */ |
|
199 void RStartupStateTimerResults::Close() |
|
200 { |
|
201 iTimerResults.Close(); |
|
202 } |
|
203 |
|
204 /** |
|
205 Startup state timer results must have been populated by a call to RetrieveResults before this method is called |
|
206 @param aIndex The index of the timing entry to retrieve |
|
207 @return The timer result entry for the given index |
|
208 */ |
|
209 TStartupStateTimerResult& RStartupStateTimerResults::At(TInt aIndex) |
|
210 { |
|
211 return iTimerResults[aIndex]; |
|
212 } |
|
213 |
|
214 /** |
|
215 @return The number of timer results retrieved |
|
216 */ |
|
217 TInt RStartupStateTimerResults::Count() |
|
218 { |
|
219 return iTimerResults.Count(); |
|
220 } |
|
221 |
|
222 //==================== For Client Requests Time Results =================== |
|
223 /** |
|
224 Retrieves a single client request timer entry from the ECom server |
|
225 @param aTimerIdx The index of the timing entry to retrieve |
|
226 @return KErrNone if successful, KErrOverflow if aTimerIdx is greater than the number of timing entries |
|
227 */ |
|
228 TInt RClientRequestTimerResults::GetTimerResult(TInt aTimerIdx, TClientRequestTimerEntry& aTimerEntry) |
|
229 { |
|
230 TInt returnedStatus; |
|
231 TPckg<TInt> statusPckg(returnedStatus); |
|
232 TPckg<TClientRequestTimerEntry> resultPckg(aTimerEntry); |
|
233 |
|
234 TIpcArgs params = TIpcArgs(EGetAccumulatedClientRequestsTimerResult, aTimerIdx, &statusPckg, &resultPckg); |
|
235 TRAPD(err, REComSession::SetGetParametersL(params)); |
|
236 if (err != KErrNone) |
|
237 { |
|
238 return err; |
|
239 } |
|
240 |
|
241 return returnedStatus; |
|
242 } |
|
243 |
|
244 /** |
|
245 Retrieves all client request timer entries from the ECom server |
|
246 */ |
|
247 void RClientRequestTimerResults::RetrieveResultsL() |
|
248 { |
|
249 TClientRequestTimerEntry timerEntry; |
|
250 TInt err = KErrNone; |
|
251 for (TInt i = 0; err == KErrNone; i++) |
|
252 { |
|
253 err = GetTimerResult(i, timerEntry); |
|
254 if (err == KErrNone) |
|
255 { |
|
256 iResults.Append(timerEntry); |
|
257 } |
|
258 else if (err != KErrOverflow) |
|
259 { |
|
260 User::Leave(err); |
|
261 } |
|
262 } |
|
263 } |
|
264 |
|
265 /** |
|
266 Determines the total time taken by ECom server servicing client requests with the given state and request type |
|
267 by going through each of the retrieved timer entries and adding up their associated times |
|
268 @pre RetrieveResultsL must have been called before this method is called |
|
269 @param aState The startup state to retrieve timer results for |
|
270 @param aRequestType The type of client request to retrieve timer results for |
|
271 @param aNumRequests On return contains the number of client requests matching aState and aRequestType |
|
272 @return The total time taken servicing client requests matching startup state aState and aRequestType |
|
273 */ |
|
274 TReal RClientRequestTimerResults::GetAccumulatedClientRequestTime(TInt aState, TEComClientRequestType aRequestType, TUint& aNumRequests) |
|
275 { |
|
276 TUint32 accumulatedTicks = 0; |
|
277 |
|
278 aNumRequests = 0; |
|
279 for (TInt i = 0; i < iResults.Count(); i++) |
|
280 { |
|
281 if (iResults[i].iState == aState && iResults[i].iClientRequestType == aRequestType) |
|
282 { |
|
283 TUint netTime = iResults[i].iEndTime - iResults[i].iStartTime; |
|
284 accumulatedTicks += netTime; |
|
285 aNumRequests++; |
|
286 } |
|
287 } |
|
288 |
|
289 return FastCountToMilliseconds(accumulatedTicks); |
|
290 } |
|
291 |
|
292 /** |
|
293 Determines the total time taken by ECom server servicing client requests with the given state |
|
294 by going through each of the retrieved timer entries and adding up their associated times |
|
295 Client request timer results must have been populated by a call to RetrieveResults before this method is called |
|
296 @param aState The startup state to retrieve timer results for |
|
297 @param aNumRequests On return contains the number of client requests matching aState |
|
298 @return The total time taken servicing client requests matching startup state aState |
|
299 */ |
|
300 TReal RClientRequestTimerResults::GetAccumulatedClientRequestTime(TInt aState, TUint& aNumRequests) |
|
301 { |
|
302 TUint32 accumulatedTicks = 0; |
|
303 |
|
304 aNumRequests = 0; |
|
305 for (TInt i = 0; i < iResults.Count(); i++) |
|
306 { |
|
307 if (iResults[i].iState == aState) |
|
308 { |
|
309 TUint netTime = iResults[i].iEndTime - iResults[i].iStartTime; |
|
310 accumulatedTicks += netTime; |
|
311 aNumRequests++; |
|
312 } |
|
313 } |
|
314 |
|
315 return FastCountToMilliseconds(accumulatedTicks); |
|
316 } |
|
317 |
|
318 /** |
|
319 Determines the total time taken by ECom server servicing client requests with the given request type |
|
320 by going through each of the retrieved timer entries and adding up their associated times |
|
321 Client request timer results must have been populated by a call to RetrieveResults before this method is called |
|
322 @param aRequestType The type of client request to retrieve timer results for |
|
323 @param aNumRequests On return contains the number of client requests matching aRequestType |
|
324 @return The total time taken servicing client requests matching startup state aRequestType |
|
325 */ |
|
326 TReal RClientRequestTimerResults::GetAccumulatedClientRequestTime(TEComClientRequestType aRequestType, TUint& aNumRequests) |
|
327 { |
|
328 TUint32 accumulatedTicks = 0; |
|
329 |
|
330 aNumRequests = 0; |
|
331 for (TInt i = 0; i < iResults.Count(); i++) |
|
332 { |
|
333 if (iResults[i].iClientRequestType == aRequestType) |
|
334 { |
|
335 TUint netTime = iResults[i].iEndTime - iResults[i].iStartTime; |
|
336 accumulatedTicks += netTime; |
|
337 aNumRequests++; |
|
338 } |
|
339 } |
|
340 |
|
341 return FastCountToMilliseconds(accumulatedTicks); |
|
342 } |
|
343 |
|
344 /** |
|
345 Determines the total time taken by ECom server servicing all client requests |
|
346 by going through each of the retrieved timer entries and adding up their associated times |
|
347 Client request timer results must have been populated by a call to RetrieveResults before this method is called |
|
348 @param aNumRequests On return contains the number of client requests |
|
349 @return The total time taken servicing client requests |
|
350 */ |
|
351 TReal RClientRequestTimerResults::GetAccumulatedClientRequestTime(TUint& aNumRequests) |
|
352 { |
|
353 TUint32 accumulatedTicks = 0; |
|
354 |
|
355 aNumRequests = 0; |
|
356 for (TInt i = 0; i < iResults.Count(); i++) |
|
357 { |
|
358 TUint netTime = iResults[i].iEndTime - iResults[i].iStartTime; |
|
359 accumulatedTicks += netTime; |
|
360 aNumRequests++; |
|
361 } |
|
362 |
|
363 return FastCountToMilliseconds(accumulatedTicks); |
|
364 } |
|
365 |
|
366 /** |
|
367 Frees any resources |
|
368 */ |
|
369 void RClientRequestTimerResults::Close() |
|
370 { |
|
371 iResults.Reset(); |
|
372 } |
|
373 |
|
374 /** |
|
375 @internalComponent |
|
376 A helper function to use SetGetParametersL to get the number of |
|
377 drives, plugins, interfaces, implementation for performance testing. |
|
378 @param aCounts a reference to a struct to store results. |
|
379 */ |
|
380 void RegistryCounts::GetRegistryCountsL(TRegistryCounts::TRegistryCountDriveType aType, TRegistryCounts& aCounts) |
|
381 { |
|
382 TPckg<TRegistryCounts> registryCountPckg(aCounts); |
|
383 TIpcArgs params = TIpcArgs(EGetRegistryCounts, aType, ®istryCountPckg); |
|
384 REComSession::SetGetParametersL(params); |
|
385 } |
|
386 |
|
387 |
|
388 //==================== For ECom Performance Time Results =================== |
|
389 /** |
|
390 @internalComponent |
|
391 A helper function to use SetGetParametersL to get the time recordings |
|
392 for performance testing. If the specified aTimerIdx is beyond the size |
|
393 of the valid recorded values then KErrOverFlow returns from the server side |
|
394 @param aTimerIdx the index of the time record to use |
|
395 @param aTimeEntry the fast time record entry |
|
396 */ |
|
397 TInt REComPerfTimeRecords::GetTimeRecordEntry(TInt aTimeIdx, TEComPerfTimeRecordEntry& aTimeEntry) |
|
398 { |
|
399 TInt returnedStatus; |
|
400 |
|
401 TPckg<TInt> statusPckg(returnedStatus); |
|
402 TPckg<TEComPerfTimeRecordEntry> resultPckg(aTimeEntry); |
|
403 |
|
404 TIpcArgs params = TIpcArgs(EGetEComPerfTimeRecord, aTimeIdx, &statusPckg, &resultPckg); |
|
405 TRAPD(err, REComSession::SetGetParametersL(params)); |
|
406 if (err != KErrNone) |
|
407 { |
|
408 return err; |
|
409 } |
|
410 |
|
411 return returnedStatus; |
|
412 } |
|
413 |
|
414 /** |
|
415 Get all ECom performance time records from server and fill up local array for further use |
|
416 */ |
|
417 void REComPerfTimeRecords::OpenL() |
|
418 { |
|
419 TEComPerfTimeRecordEntry timeEntry; |
|
420 TInt err = KErrNone; |
|
421 |
|
422 iTimeRecords.Reset(); |
|
423 |
|
424 // Get the first record from server |
|
425 TInt idx = 0; |
|
426 err = GetTimeRecordEntry(idx, timeEntry); |
|
427 while(err == KErrNone) |
|
428 { |
|
429 // If it is a valid record entry, append it to local record array, |
|
430 // and get the next entry from server. |
|
431 if (timeEntry.iType != ENullType) |
|
432 { |
|
433 iTimeRecords.Append(timeEntry); |
|
434 idx++; |
|
435 err = GetTimeRecordEntry(idx, timeEntry); |
|
436 } |
|
437 // Otherwise finished |
|
438 else |
|
439 break; |
|
440 } |
|
441 |
|
442 if (err != KErrOverflow) |
|
443 { |
|
444 User::LeaveIfError(err); |
|
445 } |
|
446 } |
|
447 |
|
448 /** |
|
449 Transform raw fast count records into real time results (in mSecs), and collect the results by specified type. |
|
450 */ |
|
451 void REComPerfTimeRecords::RetrieveResultsByTypeL(TEComPerfTimeRecordType aType, RArray<TEComPerfRealTimeResult>& aTimeResults) |
|
452 { |
|
453 TEComPerfRealTimeResult timeResult; |
|
454 TBool start = ETrue; |
|
455 TInt count = iTimeRecords.Count(); |
|
456 |
|
457 if(count) |
|
458 { |
|
459 for (TInt i = 0; i < count; i++) |
|
460 { |
|
461 // If the record has correct type |
|
462 if(iTimeRecords[i].iType == aType) |
|
463 { |
|
464 // If the record is the first of the couple, it should be the start time record |
|
465 if(start) |
|
466 { |
|
467 timeResult.iStartTime = FastCountToMilliseconds(iTimeRecords[i].iTime); |
|
468 timeResult.iType = iTimeRecords[i].iType; |
|
469 timeResult.iInfo = iTimeRecords[i].iInfo; |
|
470 start = EFalse; |
|
471 } |
|
472 // Otherwise it should be the end time record. |
|
473 else |
|
474 { |
|
475 timeResult.iEndTime = FastCountToMilliseconds(iTimeRecords[i].iTime); |
|
476 aTimeResults.Append(timeResult); |
|
477 start = ETrue; |
|
478 } |
|
479 } |
|
480 } |
|
481 } |
|
482 else // Leave if there's no records to retrieve |
|
483 { |
|
484 User::Leave(KErrNotFound); |
|
485 } |
|
486 } |
|
487 |
|
488 |
|
489 /** |
|
490 |
|
491 */ |
|
492 void REComPerfTimeRecords::RetrieveResultsInfoByTypeL(TEComPerfTimeRecordType aType, RArray<TInt>& aInfos) |
|
493 { |
|
494 TInt count = iTimeRecords.Count(); |
|
495 if(count) |
|
496 { |
|
497 for (TInt i = 0; i < count; i++) |
|
498 { |
|
499 // If the record has correct type, insert the info into aInfos array. No duplicate infos are recorded. |
|
500 if(iTimeRecords[i].iType == aType) |
|
501 { |
|
502 TInt err = aInfos.InsertInOrder(iTimeRecords[i].iInfo); |
|
503 |
|
504 if(err!=KErrAlreadyExists) |
|
505 User::LeaveIfError(err); |
|
506 } |
|
507 } |
|
508 } |
|
509 else // Leave if there's no records to retrieve |
|
510 { |
|
511 User::Leave(KErrNotFound); |
|
512 } |
|
513 } |
|
514 |
|
515 // Reset all fast count records on server |
|
516 void REComPerfTimeRecords::ResetRecordsOnServerL() |
|
517 { |
|
518 TIpcArgs params = TIpcArgs(EResetEComPerfTimeRecords); |
|
519 REComSession::SetGetParametersL(params); |
|
520 } |
|
521 |
|
522 TInt REComPerfTimeRecords::Count() |
|
523 { |
|
524 return iTimeRecords.Count(); |
|
525 } |
|
526 |
|
527 // Empty local time result array |
|
528 void REComPerfTimeRecords::Reset() |
|
529 { |
|
530 iTimeRecords.Reset(); |
|
531 } |
|
532 |
|
533 // Release resources |
|
534 void REComPerfTimeRecords::Close() |
|
535 { |
|
536 iTimeRecords.Close(); |
|
537 } |
|
538 |
|
539 //==================== For ECom Performance Heap Usage Results =================== |
|
540 /** |
|
541 @internalComponent |
|
542 */ |
|
543 void REComHeapUsageRecords::OpenL() |
|
544 { |
|
545 iHeapRecords.Reset(); |
|
546 |
|
547 // Get the first record from server |
|
548 TInt idx = 0; |
|
549 TEComPerfHeapUsage heapEntry; |
|
550 TInt err=GetHeapRecordEntry(idx,heapEntry); |
|
551 while(err == KErrNone && heapEntry.iState!=0) |
|
552 { |
|
553 //check existing array for a start item |
|
554 TBool startFound=EFalse; |
|
555 for (TInt i=0;i<iHeapRecords.Count();i++) |
|
556 { |
|
557 //if can find one this entry must be a start entry so update the heap usage |
|
558 if (iHeapRecords[i].iState==heapEntry.iState) |
|
559 { |
|
560 iHeapRecords[i].iHeapSize=heapEntry.iHeapSize-(iHeapRecords[i].iHeapSize); |
|
561 startFound=ETrue; |
|
562 break; |
|
563 } |
|
564 } |
|
565 //only append the entry if it is a new start entry |
|
566 if (!startFound) |
|
567 iHeapRecords.Append(heapEntry); |
|
568 idx++; |
|
569 err=GetHeapRecordEntry(idx,heapEntry); |
|
570 } |
|
571 |
|
572 if (err != KErrOverflow) |
|
573 { |
|
574 User::LeaveIfError(err); |
|
575 } |
|
576 } |
|
577 |
|
578 TInt REComHeapUsageRecords::GetHeapUsageAtState(TInt aState) |
|
579 { |
|
580 for (TInt i=0;i<iHeapRecords.Count();i++) |
|
581 { |
|
582 if (iHeapRecords[i].iState==aState) |
|
583 { |
|
584 return iHeapRecords[i].iHeapSize; |
|
585 } |
|
586 } |
|
587 return KErrNotFound; |
|
588 } |
|
589 |
|
590 void REComHeapUsageRecords::Close() |
|
591 { |
|
592 iHeapRecords.Reset(); |
|
593 iHeapRecords.Close(); |
|
594 } |
|
595 |
|
596 TInt REComHeapUsageRecords::GetHeapRecordEntry(TInt aHeapIdx,TEComPerfHeapUsage& aHeapEntry) |
|
597 { |
|
598 TInt returnedStatus; |
|
599 TPckg<TInt> statusPckg(returnedStatus); |
|
600 TPckg<TEComPerfHeapUsage> resultPckg(aHeapEntry); |
|
601 TIpcArgs params = TIpcArgs(EGetEComServerHeapResult, aHeapIdx,&statusPckg,&resultPckg); |
|
602 TRAPD(err, REComSession::SetGetParametersL(params)); |
|
603 return err; |
|
604 } |
|
605 |
|
606 //=========================================================== |
|
607 /** |
|
608 Converts time retrieved using FastCounter to milliseconds |
|
609 @param aFastCount The time to convert to milliseconds, retrieved using User::FastCounter |
|
610 @return The time in milliseconds corresponding to aFastCount |
|
611 */ |
|
612 TReal FastCountToMilliseconds(TInt aFastCount) |
|
613 { |
|
614 TInt freqInHz; |
|
615 HAL::Get(HAL::EFastCounterFrequency, freqInHz); |
|
616 TReal freqInkHz = freqInHz / 1000; |
|
617 return (TReal)aFastCount / freqInkHz; |
|
618 } |
|
619 |
|
620 #endif |