os/kernelhwsrv/kerneltest/e32test/active/t_cper.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-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\active\t_cper.cpp
    15 // Overview:
    16 // Test periodic timers. 
    17 // API Information:
    18 // CPeriodic, CHeartbeat
    19 // Details:	
    20 // - Create some CPeriodic timer active objects with different priorities.
    21 // - Start the periodic timers with varying delay time to start generation 
    22 // of first event and different intervals between events
    23 // - Verify the callback functions associated with each periodic are called 
    24 // in order of the time when the event occurred and considering the priority 
    25 // of the periodics.
    26 // - Create heartbeat timer with different priorities
    27 // - Start one heartbeat synchronized at ETwelveOClock 
    28 // - Start two heartbeats synchronized at ETwelveOClock, ESixOClock
    29 // - Start three heartbeats synchronized at ETwelveOClock, ESixOClock, ETwelveOClock
    30 // - Display start time and beat time for each heartbeat timer
    31 // - Check if the heap has been corrupted by all the tests.
    32 // Platforms/Drives/Compatibility:
    33 // All.
    34 // Assumptions/Requirement/Pre-requisites:
    35 // Failures and causes:
    36 // -	The first part of the test (for CPeriodic) will fail if the timers are not completed in order. 
    37 // The test on emulator is very sensitive on the background activities on PC.
    38 // Base Port information:
    39 // 
    40 //
    41 
    42 #include <e32base.h>
    43 #include <e32base_private.h>
    44 #include <e32hal.h>
    45 #include <e32test.h>
    46 #include <hal.h>
    47 #include <u32hal.h>
    48 #include <e32svr.h>
    49 
    50 LOCAL_D RTest test(_L("T_CPER"));
    51 
    52 class myScheduler: public CActiveScheduler
    53 	{
    54 public:	
    55 	virtual void Error(TInt anError) const;
    56 	};
    57 
    58 void myScheduler::Error(TInt anError) const
    59 //
    60 // virtual error handler 
    61 //
    62 	{
    63 	test.Panic(anError,_L("myScheduler::Error"));
    64 	}
    65 
    66 TInt Array[11];
    67 TTime Times[11];
    68 TInt counter = 0;
    69 
    70 CPeriodic* pPer1;
    71 CPeriodic* pPer2;
    72 CPeriodic* pPer3;
    73 CPeriodic* pPer4;
    74 CPeriodic* pPer5;
    75 CPeriodic* pPer6;
    76 CPeriodic* pPer7;
    77 
    78 TInt CallBackFn(TAny* Ptr)
    79 //
    80 // Callback function used for all periodics
    81 // On calling Ptr is actually a TInt - the periodic Id
    82 //
    83 	{
    84 	if (counter < 11)
    85 		{
    86 		Array[counter] = (TInt)Ptr;
    87 		Times[counter].HomeTime();
    88 		counter++;
    89 		}
    90 	return(0);
    91 	}
    92 
    93 TInt CallBackPanic(TAny* Ptr)
    94 //
    95 // Periodic should never get called
    96 //
    97 	{
    98 	test.Printf(_L("  PERIODIC %d HAS GONE OFF!\n"),(TInt)Ptr);
    99 	test(EFalse);
   100 	return(KErrGeneral);
   101 	}
   102 
   103 class myTimer: public CTimer
   104 	{
   105 public:
   106 	myTimer(TInt aPriority);
   107 	virtual void RunL(); 
   108 	};
   109 
   110 myTimer::myTimer(TInt aPriority) : CTimer(aPriority)
   111 //
   112 // Constructor - Creates AND ADDS TO MYSCHEDULER
   113 //	
   114 	{
   115 	ConstructL();
   116 	myScheduler::Add(this);
   117 	}
   118 
   119 void myTimer::RunL()
   120 //
   121 // The timer stops the scheduler
   122 //
   123 	{
   124 	myScheduler::Stop();
   125 	test.Printf(_L("   Timer has stopped ActiveScheduler\n"));
   126 	}
   127 
   128 
   129 //
   130 // CHeartbeat test code
   131 //
   132 class CTick : public CBase, public MBeating
   133 	{
   134 public:
   135 	virtual void Beat();
   136 	virtual void Synchronize();
   137 	void Display();
   138 	TInt iTicks;
   139 	TTime iStartTime;
   140 	TTime iTimes[4];
   141 	};
   142 void CTick::Beat()
   143 	{
   144 
   145 	test.Printf(_L("Tick\n"));
   146 	iTimes[iTicks].HomeTime();
   147 	if (++iTicks>=4)
   148 		CActiveScheduler::Stop();
   149 	}
   150 void CTick::Synchronize()
   151 	{
   152 
   153 	test.Printf(_L("Sync tick to system clock\n"));
   154 	iStartTime.HomeTime();
   155 	iTicks=0;
   156 	}
   157 
   158 void PrintTime(const TDesC& aName, const TTime& aTime)
   159 	{
   160 	TDateTime dt(aTime.DateTime());
   161 	test.Printf(_L("%S = %02d:%02d:%02d:%06d\n"),&aName,dt.Hour(),dt.Minute(),dt.Second(),dt.MicroSecond());
   162 	}
   163 
   164 void CTick::Display()
   165 	{
   166 	PrintTime(_L("Start time"),iStartTime);
   167 	TInt i;
   168 	for (i=0; i<4; i++)
   169 		{
   170 		TBuf<16> name;
   171 		name.Format(_L("Beat %d"),i);
   172 		PrintTime(name,iTimes[i]);
   173 		}
   174 	}
   175 
   176 class CTock : public CTick
   177 	{
   178 public:
   179 	virtual void Beat();
   180 	virtual void Synchronize();
   181 	};
   182 
   183 void CTock::Beat()
   184 	{
   185 
   186 	iTimes[iTicks++].HomeTime();
   187 	test.Printf(_L("Tock\n"));
   188 	}
   189 
   190 void CTock::Synchronize()
   191 	{
   192 
   193 	test.Printf(_L("Sync tock to system clock\n"));
   194 	iStartTime.HomeTime();
   195 	iTicks=0;
   196 	}
   197 
   198 class CBigTock : public CTick
   199 	{
   200 public:
   201 	virtual void Beat();
   202 	virtual void Synchronize();
   203 	};
   204 
   205 void CBigTock::Beat()
   206 	{
   207 
   208 	iTimes[iTicks++].HomeTime();
   209 	test.Printf(_L("TOCK!\n"));
   210 	}
   211 
   212 void CBigTock::Synchronize()
   213 	{
   214 
   215 	test.Printf(_L("Sync TOCK to system clock\n"));
   216 	iStartTime.HomeTime();
   217 	iTicks=0;
   218 	}
   219 
   220 void testHeartbeat()
   221 //
   222 // Test CHeartBeat
   223 //
   224 	{
   225 
   226 	test.Start(_L("Test CHeartbeat timer"));
   227 	CActiveScheduler *scheduler = new CActiveScheduler;
   228 	CActiveScheduler::Install(scheduler);
   229 
   230 	test.Next(_L("Create a beating object synchronised at ETwelveOClock"));
   231 	CTick *tick=new CTick;
   232 	CHeartbeat *pH=NULL;
   233 	TRAPD(r, pH=CHeartbeat::NewL(EPriorityNormal));
   234 	test(r==KErrNone);
   235 	test.Next(_L("Run for 4 beats on the second"));
   236 	pH->Start(ETwelveOClock, tick);
   237 	CActiveScheduler::Start();
   238 	pH->Cancel();
   239 	tick->Display();
   240 
   241 	User::After(1000000);
   242 	test.Next(_L("Create another heartbeat synchronised at ESixOClock"));
   243 	CHeartbeat *pH6=CHeartbeat::New(EPriorityNormal);
   244 	CTock *tock=new CTock;
   245 	test.Next(_L("Start both"));
   246 	pH->Start(ETwelveOClock, tick);
   247 	pH6->Start(ESixOClock, tock);
   248 	CActiveScheduler::Start();
   249 	tick->Display();
   250 	tock->Display();
   251 
   252 	pH->Cancel();
   253 	pH6->Cancel();
   254 	User::After(1000000);
   255 	test.Next(_L("Create another beating object synchronised at ESixOClock with a higher priority"));
   256 	CHeartbeat *pH2=CHeartbeat::New(EPriorityHigh);
   257 	CBigTock *bigtock=new CBigTock;
   258 	test.Next(_L("Start all"));
   259 	pH->Start(ETwelveOClock, tick);
   260 	pH6->Start(ESixOClock, tock);
   261 	pH2->Start(ESixOClock, bigtock);
   262 	CActiveScheduler::Start();
   263 	pH->Cancel();
   264 	pH2->Cancel();
   265 	pH6->Cancel();
   266 	tick->Display();
   267 	tock->Display();
   268 	bigtock->Display();
   269 
   270 	delete pH;
   271 	delete pH2;
   272 	delete pH6;
   273 	delete tock;
   274 	delete tick;
   275 	delete bigtock;
   276 	delete scheduler;
   277 	test.End();
   278 	}
   279 
   280 void testLockSpec()
   281 //
   282 // test the operators defined for TTimerLockSpec
   283 //
   284 	{
   285 /*
   286 	test.Start(_L("Test pre fix operator ++"));
   287 	TTimerLockSpec i=ETwelveOClock,k=EOneOClock,l;
   288 	TInt j;
   289 	for (j=0; j<30; j++)
   290 		{
   291 		++k=EOneOClock;
   292 		test(k==EOneOClock);
   293 		k=i;
   294 		l=++i;
   295 		switch (k)
   296 			{
   297 		case EOneOClock:
   298 			test(i==ETwoOClock);
   299 			test(l==ETwoOClock);
   300 			break;
   301 		case ETwoOClock:
   302 			test(i==EThreeOClock);
   303 			test(l==EThreeOClock);
   304 			break;
   305 		case EThreeOClock:
   306 			test(i==EFourOClock);
   307 			test(l==EFourOClock);
   308 			break;
   309 		case EFourOClock:
   310 			test(i==EFiveOClock);
   311 			test(l==EFiveOClock);
   312 			break;
   313 		case EFiveOClock:
   314 			test(i==ESixOClock);
   315 			test(l==ESixOClock);
   316 			break;
   317 		case ESixOClock:
   318 			test(i==ESevenOClock);
   319 			test(l==ESevenOClock);
   320 			break;
   321 		case ESevenOClock:
   322 			test(i==EEightOClock);
   323 			test(l==EEightOClock);
   324 			break;
   325 		case EEightOClock:
   326 			test(i==ENineOClock);
   327 			test(l==ENineOClock);
   328 			break;
   329 		case ENineOClock:
   330 			test(i==ETenOClock);
   331 			test(l==ETenOClock);
   332 			break;
   333 		case ETenOClock:
   334 			test(i==EElevenOClock);
   335 			test(l==EElevenOClock);
   336 			break;
   337 		case EElevenOClock:
   338 			test(i==ETwelveOClock);
   339 			test(l==ETwelveOClock);
   340 			break;
   341 		case ETwelveOClock:
   342 			test(i==EOneOClock);
   343 			test(l==EOneOClock);
   344 			break;
   345 			}
   346 		}
   347 
   348 	test.Next(_L("Test post fix operator ++"));
   349 	for (j=0; j<30; j++)
   350 		{
   351 		++k=EOneOClock;
   352 		test(k==EOneOClock);
   353 		k=i;
   354 		l=i++;
   355 		switch (k)
   356 			{
   357 		case EOneOClock:
   358 			test(i==ETwoOClock);
   359 			test(l==k);
   360 			break;
   361 		case ETwoOClock:
   362 			test(i==EThreeOClock);
   363 			test(l==k);
   364 			break;
   365 		case EThreeOClock:
   366 			test(i==EFourOClock);
   367 			test(l==k);
   368 			break;
   369 		case EFourOClock:
   370 			test(i==EFiveOClock);
   371 			test(l==k);
   372 			break;
   373 		case EFiveOClock:
   374 			test(i==ESixOClock);
   375 			test(l==k);
   376 			break;
   377 		case ESixOClock:
   378 			test(i==ESevenOClock);
   379 			test(l==k);
   380 			break;
   381 		case ESevenOClock:
   382 			test(i==EEightOClock);
   383 			test(l==k);
   384 			break;
   385 		case EEightOClock:
   386 			test(i==ENineOClock);
   387 			test(l==k);
   388 			break;
   389 		case ENineOClock:
   390 			test(i==ETenOClock);
   391 			test(l==k);
   392 			break;
   393 		case ETenOClock:
   394 			test(i==EElevenOClock);
   395 			test(l==k);
   396 			break;
   397 		case EElevenOClock:
   398 			test(i==ETwelveOClock);
   399 			test(l==k);
   400 			break;
   401 		case ETwelveOClock:
   402 			test(i==EOneOClock);
   403 			test(l==k);
   404 			break;
   405 			}
   406 		}
   407 	test.End();
   408 */
   409 	}
   410 
   411 
   412 GLDEF_C TInt E32Main()
   413 	{
   414 	
   415 	test.Title();
   416 	__UHEAP_MARK;
   417 	test.Start(_L("Create some CPeriodics"));
   418 
   419 	myScheduler* pScheduler = new myScheduler;
   420 	myScheduler::Install(pScheduler);
   421 
   422 	pPer1 = CPeriodic::New(0);
   423 	pPer2 = CPeriodic::NewL(0);
   424 	pPer3 = CPeriodic::NewL(10);
   425 	pPer4 = CPeriodic::NewL(100);
   426 	pPer5 = CPeriodic::NewL(100);
   427 	pPer6 = CPeriodic::NewL(100);
   428 	pPer7 = CPeriodic::NewL(100);
   429 	myTimer* pTimer = new myTimer(50);
   430 
   431 	test.Next(_L("Start them"));
   432 
   433 	TCallBack callBack1(CallBackFn,(TAny*)1);
   434 	TCallBack callBack2(CallBackFn,(TAny*)2);
   435 	TCallBack callBack3(CallBackFn,(TAny*)3);
   436 	TCallBack callBack4(CallBackPanic,(TAny*)4);
   437 	TCallBack callBack5(CallBackPanic,(TAny*)5);
   438 	TCallBack callBack6(CallBackPanic,(TAny*)6);
   439 	TCallBack callBack7(CallBackPanic,(TAny*)7);
   440 
   441 	TInt p=0;
   442 	HAL::Get(HAL::ESystemTickPeriod, p);
   443 
   444 	User::After(p); // ensure tick does not occur while starting all these timers
   445 
   446 	pPer1->Start(2*p+1,7*p+1,callBack1);	//After 3 ticks, complete every 8th tick
   447 	pPer2->Start(1,    2*p+1,callBack2);	//After 1 tick , complete every 3rd tick
   448 	pPer3->Start(7*p+1,  p+1,callBack3);	//After 8 ticks, complete every 2nd tick
   449 
   450 	pPer4->Start(KMaxTInt,KMaxTInt,callBack4);
   451 	pPer5->Start(60000000,60000000,callBack5);
   452 	pPer6->Start(KMaxTInt/91,KMaxTInt/91,callBack6);
   453 	pPer7->Start(KMaxTInt/91+1,KMaxTInt/91+1,callBack7);
   454 	pTimer->After(20*p-1); // ensure there's enough time for them to fill up the array.
   455 	/*
   456 		Time	per1   per2	  per3
   457 		  1				-
   458 		  2
   459 		  3		 -
   460 		  4				-
   461 		  5
   462 		  6
   463 		  7				-
   464 		  8					   -
   465 		  9
   466 		 10				-	   -
   467 		 11		 -			   
   468 		 12					   -
   469 		 13				-	   
   470 		 14					   -
   471 	*/
   472 
   473 	myScheduler::Start();
   474 
   475 	TInt i;
   476 	for (i=0; i<counter; ++i)
   477 		{
   478 		test.Printf(_L("   Time: %7d Periodic: %d\n"),static_cast<TUint32>(Times[i].Int64()-Times[0].Int64()),Array[i]);
   479 		}
   480 
   481 	test(Array[0]==2);
   482 	test(Array[1]==1);
   483 	test(Array[2]==2);
   484 	test(Array[3]==2);
   485 	test(Array[4]==3);
   486 	TBool normal56 = (Array[5]==3 && Array[6]==2);
   487 	TBool reverse56 = (Array[5]==2 && Array[6]==3);
   488 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1)
   489 		{
   490 		// If there are multiple processors the order of 'simultaneous' timers is undefined since
   491 		// the test may get to run as soon as the first timer is completed, instead of only after
   492 		// the timer thread blocks, which would be after both timers completed.
   493 		test(normal56 || reverse56);
   494 		}
   495 	else
   496 		test(normal56);
   497 	test(Array[7]==1);
   498 	test(Array[8]==3);
   499 	test(Array[9]==2);
   500 	test(Array[10]==3);
   501 
   502 	test.Next(_L("Destroy them"));
   503 
   504 	delete pPer1;
   505 	delete pPer2;
   506 	delete pPer3;
   507 	delete pPer4;
   508 	delete pPer5;
   509 	delete pPer6;
   510 	delete pPer7;
   511 	delete pTimer;
   512 	delete pScheduler;
   513 
   514 	test.Next(_L("Test CHeartbeat"));
   515 	testHeartbeat();
   516 	test.Next(_L("Test TTimerLockSpec"));
   517 	testLockSpec();
   518 	__UHEAP_MARKEND;
   519 	test.End();
   520 	return(KErrNone);
   521 	}