os/kernelhwsrv/kerneltest/e32test/system/t_tock.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1997-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 // e32test\system\t_tock.cpp
    15 // Overview:
    16 // Test tick-based timers
    17 // API Information:
    18 // RTimer
    19 // Details:
    20 // - Create a number of periodic timers, start each and change the time
    21 // offset via TLocale::SetUniversalTimeOffset(). Print the results.
    22 // - Create a number of periodic timers, start each and change the system
    23 // time. Print the results.
    24 // - Create a number of periodic timers, start each and change the system
    25 // time in a second thread. Print the results.
    26 // - Create a number of periodic timers, start each along with a background
    27 // timer. Print the results.
    28 // - Create a number of periodic timers, start each and change the system
    29 // time and tick delay. Print the results.
    30 // Platforms/Drives/Compatibility:
    31 // All.
    32 // Assumptions/Requirement/Pre-requisites:
    33 // Failures and causes:
    34 // Base Port information:
    35 // 
    36 //
    37 
    38 #include <e32test.h>
    39 #include <e32uid.h>
    40 #include "d_tick.h"
    41 
    42 RTest test(_L("T_TOCK"));
    43 RTickTest ticktest;
    44 TInt ActiveCount;
    45 TInt ErrorCount;
    46 
    47 TBool PauseOnError = 0;
    48 #define GETCH()		(PauseOnError&&test.Getch())
    49 
    50 #define TEST(c)		((void)((c)||(test.Printf(_L("Failed at line %d\n"),__LINE__),GETCH(),test(0),0)))
    51 #define CHECK(c)	((void)(((c)==0)||(test.Printf(_L("Error %d at line %d\n"),(c),__LINE__),GETCH(),test(0),0)))
    52 
    53 const TPtrC KLddFileName=_L("D_TICK.LDD");
    54 
    55 class CTickTest : public CActive
    56 	{
    57 public:
    58 	CTickTest(TInt aPriority, TInt aId, RTickTest aLdd);
    59 	~CTickTest();
    60 	virtual void RunL();
    61 	virtual void DoCancel();
    62 public:
    63 	void StartPeriodic(TInt aInterval, TInt aCount);
    64 	void StartNShotRel(TInt aMin, TInt aRange, TInt aCount);
    65 	void StartNShotAbs(TInt aMin, TInt aRange, TInt aCount);
    66 	void StartNShotDelay(TInt aPeriod, TInt aDelay, TInt aCount);
    67 	void GetInfo(STickTestInfo& aInfo);
    68 public:
    69 	TInt iId;
    70 	TInt iCount;
    71 	TInt iMin;
    72 	TInt iRange;
    73 	TInt64 iErrorAcc;
    74 	RTickTest iLdd;
    75 	STickTestInfo iInfo;
    76 	};
    77 
    78 class CBackgroundTimer : public CActive
    79 	{
    80 public:
    81 	static CBackgroundTimer* NewL(TInt aPriority);
    82 	CBackgroundTimer(TInt aPriority);
    83 	~CBackgroundTimer();
    84 	virtual void RunL();
    85 	virtual void DoCancel();
    86 	void Start();
    87 public:
    88 	RTimer iShort;
    89 	RTimer iLong;
    90 	TRequestStatus iLongStatus;
    91 	};
    92 
    93 CTickTest* TickTest[KMaxTimers];
    94 CIdle* Idler;
    95 CBackgroundTimer* BackgroundTimer;
    96 
    97 CTickTest::CTickTest(TInt aPriority, TInt aId, RTickTest aLdd)
    98 	:	CActive(aPriority),
    99 		iId(aId),
   100 		iLdd(aLdd)
   101 	{
   102 	}
   103 
   104 CTickTest::~CTickTest()
   105 	{
   106 	Cancel();
   107 	iLdd.SetHandle(0);
   108 	}
   109 
   110 void CTickTest::StartPeriodic(TInt aInterval, TInt aCount)
   111 	{
   112 	TInt r=iLdd.StartPeriodic(iStatus,iId,aInterval,aCount);
   113 	if (r!=KErrNone)
   114 		{
   115 		TRequestStatus* pS=&iStatus;
   116 		User::RequestComplete(pS,r);
   117 		}
   118 	SetActive();
   119 	}
   120 
   121 void CTickTest::StartNShotRel(TInt aMin, TInt aRange, TInt aCount)
   122 	{
   123 	TInt c=aCount;
   124 	if (aCount<0)
   125 		{
   126 		iCount=-aCount;
   127 		c=1;
   128 		}
   129 	iMin=aMin;
   130 	iRange=aRange;
   131 	iErrorAcc=0;
   132 	iInfo.iMinErr=KMaxTInt;
   133 	iInfo.iMaxErr=KMinTInt;
   134 	iInfo.iCount=0;
   135 	iInfo.iRequestedCount=iCount;
   136 	iInfo.iTotalTime=0;
   137 	TInt r=iLdd.StartNShotRel(iStatus,iId,aMin,aRange,c);
   138 	if (r!=KErrNone)
   139 		{
   140 		TRequestStatus* pS=&iStatus;
   141 		User::RequestComplete(pS,r);
   142 		}
   143 	SetActive();
   144 	}
   145 
   146 void CTickTest::StartNShotAbs(TInt aMin, TInt aRange, TInt aCount)
   147 	{
   148 	TInt r=iLdd.StartNShotAbs(iStatus,iId,aMin,aRange,aCount);
   149 	if (r!=KErrNone)
   150 		{
   151 		TRequestStatus* pS=&iStatus;
   152 		User::RequestComplete(pS,r);
   153 		}
   154 	SetActive();
   155 	}
   156 
   157 void CTickTest::StartNShotDelay(TInt aPeriod, TInt aDelay, TInt aCount)
   158 	{
   159 	iCount=0;
   160 	TInt r=iLdd.StartNShotDelay(iStatus,iId,aPeriod,aDelay,aCount);
   161 	if (r!=KErrNone)
   162 		{
   163 		TRequestStatus* pS=&iStatus;
   164 		User::RequestComplete(pS,r);
   165 		}
   166 	SetActive();
   167 	}
   168 
   169 void CTickTest::GetInfo(STickTestInfo& aInfo)
   170 	{
   171 	iLdd.GetInfo(iId,aInfo);
   172 	}
   173 
   174 void CTickTest::RunL()
   175 	{
   176 	if (iStatus!=KErrNone)
   177 		{
   178 		test.Printf(_L("Timer %d error %d\n"),iId,iStatus.Int());
   179 		++ErrorCount;
   180 		CActiveScheduler::Stop();
   181 		return;
   182 		}
   183 	if (iCount==0)
   184 		GetInfo(iInfo);
   185 	else
   186 		{
   187 		STickTestInfo info;
   188 		iLdd.GetInfo(iId,info);
   189 		TInt err=info.iMinErr;
   190 		if (err<iInfo.iMinErr)
   191 			iInfo.iMinErr=err;
   192 		if (err>iInfo.iMaxErr)
   193 			iInfo.iMaxErr=err;
   194 		++iInfo.iCount;
   195 		iErrorAcc+=err;
   196 		if (--iCount)
   197 			{
   198 			TInt r=iLdd.StartNShotRel(iStatus,iId,iMin,iRange,1);
   199 			if (r!=KErrNone)
   200 				{
   201 				TRequestStatus* pS=&iStatus;
   202 				User::RequestComplete(pS,r);
   203 				}
   204 			SetActive();
   205 			return;
   206 			}
   207 		iInfo.iAvgErr=I64INT(iErrorAcc/TInt64(iInfo.iCount));
   208 		}
   209 	test.Printf(_L("Timer %d\n"),iId);
   210 	if (!--ActiveCount)
   211 		CActiveScheduler::Stop();
   212 	}
   213 
   214 void CTickTest::DoCancel()
   215 	{
   216 	iLdd.Stop(iId);
   217 	}
   218 
   219 CBackgroundTimer::CBackgroundTimer(TInt aPriority)
   220 	:	CActive(aPriority)
   221 	{
   222 	}
   223 
   224 CBackgroundTimer::~CBackgroundTimer()
   225 	{
   226 	iShort.Close();
   227 	iLong.Close();
   228 	}
   229 
   230 void CBackgroundTimer::Start()
   231 	{
   232 	iLong.After(iLongStatus, 100000);
   233 	iShort.After(iStatus, 20000);
   234 	SetActive();
   235 	}
   236 
   237 void CBackgroundTimer::RunL()
   238 	{
   239 	iLong.Cancel();
   240 	User::WaitForRequest(iLongStatus);
   241 	Start();
   242 	}
   243 
   244 void CBackgroundTimer::DoCancel()
   245 	{
   246 	iShort.Cancel();
   247 	iLong.Cancel();
   248 	User::WaitForRequest(iLongStatus);
   249 	}
   250 
   251 CBackgroundTimer* CBackgroundTimer::NewL(TInt aPriority)
   252 	{
   253 	CBackgroundTimer* pB=new (ELeave) CBackgroundTimer(aPriority);
   254 	TInt r=pB->iShort.CreateLocal();
   255 	if (r==KErrNone)
   256 		r=pB->iLong.CreateLocal();
   257 	if (r!=KErrNone)
   258 		{
   259 		delete pB;
   260 		pB=NULL;
   261 		}
   262 	return pB;
   263 	}
   264 
   265 void InitialiseL()
   266 	{
   267 	CActiveScheduler* pS=new (ELeave) CActiveScheduler;
   268 	CActiveScheduler::Install(pS);
   269 	TInt i;
   270 	for (i=0; i<KMaxTimers; ++i)
   271 		{
   272 		TickTest[i]=new (ELeave) CTickTest(0,i,ticktest);
   273 		CActiveScheduler::Add(TickTest[i]);
   274 		}
   275 	Idler=CIdle::NewL(-100);
   276 	BackgroundTimer=CBackgroundTimer::NewL(-10);
   277 	CActiveScheduler::Add(BackgroundTimer);
   278 	}
   279 
   280 void PrintInfo(TInt aId, STickTestInfo& a)
   281 	{
   282 	test.Printf(_L("%1d: min=%-6d max=%-6d avg=%-6d tot=%-10u count=%d rcount=%d\n"),aId,a.iMinErr,a.iMaxErr,a.iAvgErr,a.iTotalTime,a.iCount,a.iRequestedCount);
   283 	}
   284 
   285 void PrintInfo(TInt aId)
   286 	{
   287 	PrintInfo(aId, TickTest[aId]->iInfo);
   288 	}
   289 
   290 void PrintInfo()
   291 	{
   292 	TInt i;
   293 	for (i=0; i<KMaxTimers; ++i)
   294 		PrintInfo(i);
   295 	}
   296 
   297 TInt ChangeOffset(TAny*)
   298 	{
   299 	User::SetUTCOffset(3600);
   300 	User::SetUTCOffset(0);
   301 	return 1;	// so we run again
   302 	}
   303 
   304 TInt ChangeTime(TAny*)
   305 	{
   306 	TTime now;
   307 	now.UniversalTime();
   308 	User::SetUTCTime(now+TTimeIntervalSeconds(1000));
   309 	User::SetUTCTime(now);
   310 	return 1;	// so we run again
   311 	}
   312 
   313 TInt ChangeTimeThread(TAny*)
   314 	{
   315 	FOREVER
   316 		{
   317 		User::AfterHighRes(3000);
   318 		TTime now;
   319 		now.UniversalTime();
   320 		User::SetUTCTime(now+TTimeIntervalSeconds(1000));
   321 		User::AfterHighRes(1000);
   322 		User::SetUTCTime(now);
   323 		}
   324 	}
   325 
   326 GLDEF_C TInt E32Main()
   327 //
   328 // Test tick-based timers
   329 //
   330     {
   331 
   332 //	test.SetLogged(EFalse);
   333 	test.Title();
   334 
   335 	test.Start(_L("Load test LDD"));
   336 	TInt r=User::LoadLogicalDevice(KLddFileName);
   337 	TEST(r==KErrNone || r==KErrAlreadyExists);
   338 	
   339 	r=ticktest.Open();
   340 	CHECK(r);
   341 
   342 	test.Next(_L("Create test objects"));
   343 	TRAP(r, InitialiseL());
   344 	CHECK(r);
   345 
   346 	test.Next(_L("Periodics with changing home time offset"));
   347 	TickTest[0]->StartPeriodic(3,1000);
   348 	TickTest[1]->StartPeriodic(5,600);
   349 	TickTest[2]->StartPeriodic(7,400);
   350 	TickTest[3]->StartPeriodic(11,300);
   351 	TickTest[4]->StartPeriodic(13,30);
   352 	TickTest[5]->StartPeriodic(19,30);
   353 	TickTest[6]->StartPeriodic(23,30);
   354 	TickTest[7]->StartPeriodic(37,30);
   355 	Idler->Start(TCallBack(ChangeOffset,NULL));
   356 	ActiveCount=8;
   357 	ErrorCount=0;
   358 	CActiveScheduler::Start();
   359 	Idler->Cancel();
   360 	PrintInfo();
   361 
   362 	test.Next(_L("Periodics with changing system time"));
   363 	TickTest[0]->StartPeriodic(3,1000);
   364 	TickTest[1]->StartPeriodic(5,600);
   365 	TickTest[2]->StartPeriodic(7,400);
   366 	TickTest[3]->StartPeriodic(11,300);
   367 	TickTest[4]->StartPeriodic(13,30);
   368 	TickTest[5]->StartPeriodic(19,30);
   369 	TickTest[6]->StartPeriodic(23,30);
   370 	TickTest[7]->StartPeriodic(37,30);
   371 	Idler->Start(TCallBack(ChangeTime,NULL));
   372 	ActiveCount=8;
   373 	ErrorCount=0;
   374 	CActiveScheduler::Start();
   375 	Idler->Cancel();
   376 	PrintInfo();
   377 
   378 	test.Next(_L("Periodics with changing system time in second thread"));
   379 	RThread t;
   380 	r=t.Create(KNullDesC(),ChangeTimeThread,0x1000,NULL,NULL);
   381 	CHECK(r);
   382 	t.SetPriority(EPriorityMore);
   383 	TickTest[0]->StartPeriodic(3,1000);
   384 	TickTest[1]->StartPeriodic(5,600);
   385 	TickTest[2]->StartPeriodic(7,400);
   386 	TickTest[3]->StartPeriodic(11,300);
   387 	TickTest[4]->StartPeriodic(13,30);
   388 	TickTest[5]->StartPeriodic(19,30);
   389 	TickTest[6]->StartPeriodic(23,30);
   390 	TickTest[7]->StartPeriodic(37,30);
   391 	Idler->Start(TCallBack(ChangeTime,NULL));
   392 	ActiveCount=8;
   393 	ErrorCount=0;
   394 	t.Resume();
   395 	CActiveScheduler::Start();
   396 	Idler->Cancel();
   397 	TRequestStatus s;
   398 	t.Logon(s);
   399 	t.Kill(0);
   400 	User::WaitForRequest(s);
   401 	test(t.ExitType()==EExitKill);
   402 	test(t.ExitReason()==0);
   403 	test(s==0);
   404 	CLOSE_AND_WAIT(t);
   405 	PrintInfo();
   406 
   407 	test.Next(_L("Periodics with background timer"));
   408 	TickTest[0]->StartPeriodic(3,1000);
   409 	TickTest[1]->StartPeriodic(5,600);
   410 	TickTest[2]->StartPeriodic(7,400);
   411 	TickTest[3]->StartPeriodic(11,300);
   412 	TickTest[4]->StartPeriodic(13,30);
   413 	TickTest[5]->StartPeriodic(19,30);
   414 	TickTest[6]->StartPeriodic(23,30);
   415 	TickTest[7]->StartPeriodic(37,30);
   416 	BackgroundTimer->Start();
   417 	ActiveCount=8;
   418 	ErrorCount=0;
   419 	CActiveScheduler::Start();
   420 	BackgroundTimer->Cancel();
   421 	PrintInfo();
   422 
   423 	test.Next(_L("Periodics with changing system time and tick delay"));
   424 	TickTest[0]->StartPeriodic(3,1000);
   425 	TickTest[1]->StartPeriodic(5,600);
   426 	TickTest[2]->StartPeriodic(7,400);
   427 	TickTest[3]->StartPeriodic(11,300);
   428 	TickTest[4]->StartPeriodic(13,30);
   429 	TickTest[5]->StartPeriodic(19,30);
   430 	TickTest[6]->StartPeriodic(23,30);
   431 	TickTest[7]->StartNShotDelay(17,30,200);
   432 	Idler->Start(TCallBack(ChangeTime,NULL));
   433 	ActiveCount=8;
   434 	ErrorCount=0;
   435 	CActiveScheduler::Start();
   436 	Idler->Cancel();
   437 	PrintInfo();
   438 
   439 	ticktest.Close();
   440 	test.End();
   441 	return(KErrNone);
   442     }
   443