| 0 |      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 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 | // Overview:
 | 
|  |     15 | // The test measures the duration of the user-side timer services.
 | 
|  |     16 | // API Information:
 | 
|  |     17 | // User::After(...)
 | 
|  |     18 | // User::At(...)
 | 
|  |     19 | // User::AfterHighRes(...)
 | 
|  |     20 | // Details:
 | 
|  |     21 | // - Calls time services a number of times with the same input arguments.
 | 
|  |     22 | // - Records and prints the minimum and maximum duration of each test case.
 | 
|  |     23 | // - Tests the duration of User::After and User::AfterHighRes on target.
 | 
|  |     24 | // Platforms/Drives/Compatibility:
 | 
|  |     25 | // Emulator and Hardware (Automatic). 
 | 
|  |     26 | // Assumptions/Requirement/Pre-requisites:
 | 
|  |     27 | // Failures and causes:
 | 
|  |     28 | // The test can fail only on target.
 | 
|  |     29 | // - The duration of Timer::After(aTime) is not within the limits (from <aTime> to <aTime + 1000000/64+2*NanoKarnelTickPeriod>)
 | 
|  |     30 | // - The duration of Timer::AfterHighRes(aTime) is not within the limits (from <aTime> to <aTime+2*NanoKarnelTickPeriod>)
 | 
|  |     31 | // Base Port information:
 | 
|  |     32 | // 
 | 
|  |     33 | //
 | 
|  |     34 | 
 | 
|  |     35 | #include <e32std.h>
 | 
|  |     36 | #include <e32std_private.h>
 | 
|  |     37 | #include <e32test.h>
 | 
|  |     38 | #include <e32math.h>
 | 
|  |     39 | #include <e32svr.h>
 | 
|  |     40 | #include <hal.h>
 | 
|  |     41 | 
 | 
|  |     42 | LOCAL_D RTest test(_L("T_TIMERDURATION"));
 | 
|  |     43 | 
 | 
|  |     44 | // Max number of different time values measured
 | 
|  |     45 | const TInt KMaxTimeValues = 12;
 | 
|  |     46 | 
 | 
|  |     47 | // number of times measurement taken to average
 | 
|  |     48 | const TInt KMaxTimeMeasurements = 20;
 | 
|  |     49 | TInt MaxTimeMeasurements;
 | 
|  |     50 | TInt TimeRawMS[KMaxTimeMeasurements];//Holds the ROW time in Kernel ticks
 | 
|  |     51 | 
 | 
|  |     52 | TInt* TimeValue;
 | 
|  |     53 | TInt TimeMin[KMaxTimeValues];
 | 
|  |     54 | TInt TimeMax[KMaxTimeValues];
 | 
|  |     55 | 	
 | 
|  |     56 | void calcStats(TInt i)
 | 
|  |     57 | 	{
 | 
|  |     58 | 	TimeMin[i]=TimeRawMS[0];
 | 
|  |     59 | 	TimeMax[i]=TimeRawMS[0];
 | 
|  |     60 | 	for (TInt j=1; j<MaxTimeMeasurements; ++j)
 | 
|  |     61 | 			{
 | 
|  |     62 | 			if (TimeMin[i]>TimeRawMS[j]) TimeMin[i]=TimeRawMS[j];
 | 
|  |     63 | 			if (TimeMax[i]<TimeRawMS[j]) TimeMax[i]=TimeRawMS[j];
 | 
|  |     64 | 			}
 | 
|  |     65 | 	}
 | 
|  |     66 | 
 | 
|  |     67 | void printStats()
 | 
|  |     68 | 	{
 | 
| 44 |     69 | 	test.Printf(_L("Value\tMin\tMax"));
 | 
| 0 |     70 | 	for (TInt i=0;i<KMaxTimeValues;++i)
 | 
|  |     71 | 		{
 | 
|  |     72 | 		if (TimeValue[i]<0) break;
 | 
| 44 |     73 | 		test.Printf(_L("%d\t%d\t%d"),TimeValue[i],TimeMin[i],TimeMax[i]);
 | 
| 0 |     74 | 		}
 | 
|  |     75 | 	}
 | 
|  |     76 | 
 | 
|  |     77 | #define __BEFORE_WAIT__ \
 | 
| 44 |     78 | 	test.Printf(_L("Measuring value(%d measurements at each value):"), MaxTimeMeasurements);\
 | 
| 0 |     79 | 	for (i=0;i<KMaxTimeValues;++i)\
 | 
|  |     80 | 		{\
 | 
|  |     81 | 		if (TimeValue[i]<0) break;\
 | 
| 44 |     82 | 		test.Printf(_L("%d microseconds ..."),TimeValue[i]);\
 | 
| 0 |     83 | 		value = TimeValue[i];\
 | 
|  |     84 | 		for (j=0; j<MaxTimeMeasurements; ++j)\
 | 
|  |     85 | 			{\
 | 
|  |     86 | 			User::AfterHighRes((Math::Random()&0xf)*1000);\
 | 
|  |     87 | 	
 | 
|  |     88 | #define __MEASURE1__ tick1 = User::NTickCount();
 | 
|  |     89 | 
 | 
|  |     90 | #define __MEASURE2__ tick2 = User::NTickCount();
 | 
|  |     91 | 
 | 
|  |     92 | #define __AFTER_WAIT__ \
 | 
|  |     93 | 			TimeRawMS[j]=(tick2-tick1)*tickPeriod;\
 | 
|  |     94 | 			}\
 | 
|  |     95 | 		calcStats(i);\
 | 
|  |     96 | 		}\
 | 
|  |     97 | 	printStats();\
 | 
|  |     98 | 
 | 
|  |     99 | GLDEF_C TInt E32Main()
 | 
|  |    100 |     {
 | 
|  |    101 |     TInt i,j;
 | 
|  |    102 | 	test.Title();
 | 
|  |    103 | 	test.Start(_L("Timer resolution test"));
 | 
|  |    104 | 	test.SetLogged(ETrue);
 | 
|  |    105 | 	RThread This;
 | 
|  |    106 | 	This.SetPriority(EPriorityRealTime);
 | 
|  |    107 | 	TUint tick1,tick2;
 | 
|  |    108 | 	TInt value, tickPeriod;
 | 
|  |    109 | 	HAL::Get(HAL::ENanoTickPeriod, tickPeriod);
 | 
| 44 |    110 | 	test.Printf(_L("tickPeriod=%d"),tickPeriod);
 | 
| 0 |    111 | ///////////////////////////////////////////
 | 
|  |    112 | 	test.Next(_L("Calibrate"));
 | 
|  |    113 | 	MaxTimeMeasurements = KMaxTimeMeasurements;
 | 
|  |    114 | 	TInt TimeValues1[KMaxTimeValues]={0,-1};
 | 
|  |    115 | 	TimeValue = &TimeValues1[0];
 | 
|  |    116 | 	__BEFORE_WAIT__
 | 
|  |    117 | 	__MEASURE1__
 | 
|  |    118 | 	__MEASURE2__
 | 
|  |    119 | 	__AFTER_WAIT__
 | 
|  |    120 | ///////////////////////////////////////////
 | 
|  |    121 | 	test.Next(_L("User::After"));
 | 
|  |    122 | 	TInt TimeValues2[KMaxTimeValues]={10000, 40000,80000,160000,320000,-1};
 | 
|  |    123 | 	TimeValue = &TimeValues2[0];
 | 
|  |    124 | 	__BEFORE_WAIT__
 | 
|  |    125 | 	__MEASURE1__
 | 
|  |    126 | 			User::After(value);
 | 
|  |    127 | 	__MEASURE2__
 | 
|  |    128 | 	__AFTER_WAIT__
 | 
|  |    129 | #if defined(__EPOC32__)
 | 
|  |    130 | 	//Check that User::After calls completed within boundaries
 | 
|  |    131 |     TInt k;
 | 
|  |    132 | 	for (k = 0; k<KMaxTimeValues; k++)
 | 
|  |    133 | 		{
 | 
|  |    134 | 		if (TimeValue[k] == -1) break;
 | 
|  |    135 | 		test(TimeValue[k] <= TimeMin[k]);
 | 
|  |    136 | 		TInt aTimerResolution = 1000000/64;
 | 
|  |    137 | 		test((TimeValue[k] + aTimerResolution +2*tickPeriod) >= TimeMax[k]);
 | 
|  |    138 | 		}
 | 
|  |    139 | #endif
 | 
|  |    140 | ///////////////////////////////////////////
 | 
|  |    141 | 	test.Next(_L("User::At"));
 | 
|  |    142 | 	MaxTimeMeasurements = KMaxTimeMeasurements/2;
 | 
|  |    143 | 	TInt TimeValues3[KMaxTimeValues]={950000,1000000,-1};
 | 
|  |    144 | 	TimeValue = &TimeValues3[0];
 | 
|  |    145 | 	TTime time;
 | 
|  |    146 | 	time.Set(_L("20050101:000001.000000"));
 | 
|  |    147 | 	User::SetHomeTime(time);
 | 
|  |    148 | 	__BEFORE_WAIT__
 | 
|  |    149 | 			time.HomeTime();
 | 
|  |    150 | 			time += (TTimeIntervalMicroSeconds32)value;
 | 
|  |    151 | 	__MEASURE1__
 | 
|  |    152 | 			User::At(time);
 | 
|  |    153 | 	__MEASURE2__
 | 
|  |    154 | 	__AFTER_WAIT__
 | 
|  |    155 | ///////////////////////////////////////////
 | 
|  |    156 | 	test.Next(_L("User::AfterHighRes"));
 | 
|  |    157 | 	MaxTimeMeasurements = KMaxTimeMeasurements;
 | 
|  |    158 | 	TInt TimeValues4[KMaxTimeValues]={1000,2000,4000,8000,16000,32000,64000,128000,-1};
 | 
|  |    159 | 	TimeValue = &TimeValues4[0];
 | 
|  |    160 | 	__BEFORE_WAIT__
 | 
|  |    161 | 	__MEASURE1__
 | 
|  |    162 | 			User::AfterHighRes(value);
 | 
|  |    163 | 	__MEASURE2__
 | 
|  |    164 | 	__AFTER_WAIT__
 | 
|  |    165 | #if defined(__EPOC32__)
 | 
|  |    166 | 	//Check that User::AfterHighRes calls completed within boundaries
 | 
|  |    167 | 	for (k = 0; k<KMaxTimeValues; k++)
 | 
|  |    168 | 		{
 | 
|  |    169 | 		if (TimeValue[k] == -1) break;
 | 
|  |    170 | 		test(TimeValue[k] <= TimeMin[k]);
 | 
|  |    171 | 		test((TimeValue[k] + 2*tickPeriod) >= TimeMax[k]);
 | 
|  |    172 | 		}
 | 
|  |    173 | #endif
 | 
|  |    174 | ///////////////////////////////////////////
 | 
|  |    175 | 	test.End();
 | 
|  |    176 | 	return(KErrNone);
 | 
|  |    177 | 	}
 |