kerneltest/e32test/active/t_timerduration.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
child 43 c1f20ce4abcf
permissions -rw-r--r--
Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h) Have multiple extension sections in the bld.inf, one for each version of the compiler. The RVCT version building the tools will build the runtime libraries for its version, but make sure we extract all the other versions from zip archives. Also add the archive for RVCT4.

// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// Overview:
// The test measures the duration of the user-side timer services.
// API Information:
// User::After(...)
// User::At(...)
// User::AfterHighRes(...)
// Details:
// - Calls time services a number of times with the same input arguments.
// - Records and prints the minimum and maximum duration of each test case.
// - Tests the duration of User::After and User::AfterHighRes on target.
// Platforms/Drives/Compatibility:
// Emulator and Hardware (Automatic). 
// Assumptions/Requirement/Pre-requisites:
// Failures and causes:
// The test can fail only on target.
// - The duration of Timer::After(aTime) is not within the limits (from <aTime> to <aTime + 1000000/64+2*NanoKarnelTickPeriod>)
// - The duration of Timer::AfterHighRes(aTime) is not within the limits (from <aTime> to <aTime+2*NanoKarnelTickPeriod>)
// Base Port information:
// 
//

#include <e32std.h>
#include <e32std_private.h>
#include <e32test.h>
#include <e32math.h>
#include <e32svr.h>
#include <hal.h>

LOCAL_D RTest test(_L("T_TIMERDURATION"));

// Max number of different time values measured
const TInt KMaxTimeValues = 12;

// number of times measurement taken to average
const TInt KMaxTimeMeasurements = 20;
TInt MaxTimeMeasurements;
TInt TimeRawMS[KMaxTimeMeasurements];//Holds the ROW time in Kernel ticks

TInt* TimeValue;
TInt TimeMin[KMaxTimeValues];
TInt TimeMax[KMaxTimeValues];
	
void calcStats(TInt i)
	{
	TimeMin[i]=TimeRawMS[0];
	TimeMax[i]=TimeRawMS[0];
	for (TInt j=1; j<MaxTimeMeasurements; ++j)
			{
			if (TimeMin[i]>TimeRawMS[j]) TimeMin[i]=TimeRawMS[j];
			if (TimeMax[i]<TimeRawMS[j]) TimeMax[i]=TimeRawMS[j];
			}
	}

void printStats()
	{
	test.Printf(_L("Value\tMin\tMax"));
	for (TInt i=0;i<KMaxTimeValues;++i)
		{
		if (TimeValue[i]<0) break;
		test.Printf(_L("%d\t%d\t%d"),TimeValue[i],TimeMin[i],TimeMax[i]);
		}
	}

#define __BEFORE_WAIT__ \
	test.Printf(_L("Measuring value(%d measurements at each value):"), MaxTimeMeasurements);\
	for (i=0;i<KMaxTimeValues;++i)\
		{\
		if (TimeValue[i]<0) break;\
		test.Printf(_L("%d microseconds ..."),TimeValue[i]);\
		value = TimeValue[i];\
		for (j=0; j<MaxTimeMeasurements; ++j)\
			{\
			User::AfterHighRes((Math::Random()&0xf)*1000);\
	
#define __MEASURE1__ tick1 = User::NTickCount();

#define __MEASURE2__ tick2 = User::NTickCount();

#define __AFTER_WAIT__ \
			TimeRawMS[j]=(tick2-tick1)*tickPeriod;\
			}\
		calcStats(i);\
		}\
	printStats();\

GLDEF_C TInt E32Main()
    {
    TInt i,j;
	test.Title();
	test.Start(_L("Timer resolution test"));
	test.SetLogged(ETrue);
	RThread This;
	This.SetPriority(EPriorityRealTime);
	TUint tick1,tick2;
	TInt value, tickPeriod;
	HAL::Get(HAL::ENanoTickPeriod, tickPeriod);
	test.Printf(_L("tickPeriod=%d"),tickPeriod);
///////////////////////////////////////////
	test.Next(_L("Calibrate"));
	MaxTimeMeasurements = KMaxTimeMeasurements;
	TInt TimeValues1[KMaxTimeValues]={0,-1};
	TimeValue = &TimeValues1[0];
	__BEFORE_WAIT__
	__MEASURE1__
	__MEASURE2__
	__AFTER_WAIT__
///////////////////////////////////////////
	test.Next(_L("User::After"));
	TInt TimeValues2[KMaxTimeValues]={10000, 40000,80000,160000,320000,-1};
	TimeValue = &TimeValues2[0];
	__BEFORE_WAIT__
	__MEASURE1__
			User::After(value);
	__MEASURE2__
	__AFTER_WAIT__
#if defined(__EPOC32__)
	//Check that User::After calls completed within boundaries
    TInt k;
	for (k = 0; k<KMaxTimeValues; k++)
		{
		if (TimeValue[k] == -1) break;
		test(TimeValue[k] <= TimeMin[k]);
		TInt aTimerResolution = 1000000/64;
		test((TimeValue[k] + aTimerResolution +2*tickPeriod) >= TimeMax[k]);
		}
#endif
///////////////////////////////////////////
	test.Next(_L("User::At"));
	MaxTimeMeasurements = KMaxTimeMeasurements/2;
	TInt TimeValues3[KMaxTimeValues]={950000,1000000,-1};
	TimeValue = &TimeValues3[0];
	TTime time;
	time.Set(_L("20050101:000001.000000"));
	User::SetHomeTime(time);
	__BEFORE_WAIT__
			time.HomeTime();
			time += (TTimeIntervalMicroSeconds32)value;
	__MEASURE1__
			User::At(time);
	__MEASURE2__
	__AFTER_WAIT__
///////////////////////////////////////////
	test.Next(_L("User::AfterHighRes"));
	MaxTimeMeasurements = KMaxTimeMeasurements;
	TInt TimeValues4[KMaxTimeValues]={1000,2000,4000,8000,16000,32000,64000,128000,-1};
	TimeValue = &TimeValues4[0];
	__BEFORE_WAIT__
	__MEASURE1__
			User::AfterHighRes(value);
	__MEASURE2__
	__AFTER_WAIT__
#if defined(__EPOC32__)
	//Check that User::AfterHighRes calls completed within boundaries
	for (k = 0; k<KMaxTimeValues; k++)
		{
		if (TimeValue[k] == -1) break;
		test(TimeValue[k] <= TimeMin[k]);
		test((TimeValue[k] + 2*tickPeriod) >= TimeMax[k]);
		}
#endif
///////////////////////////////////////////
	test.End();
	return(KErrNone);
	}