1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/active/t_cper.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,521 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\active\t_cper.cpp
1.18 +// Overview:
1.19 +// Test periodic timers.
1.20 +// API Information:
1.21 +// CPeriodic, CHeartbeat
1.22 +// Details:
1.23 +// - Create some CPeriodic timer active objects with different priorities.
1.24 +// - Start the periodic timers with varying delay time to start generation
1.25 +// of first event and different intervals between events
1.26 +// - Verify the callback functions associated with each periodic are called
1.27 +// in order of the time when the event occurred and considering the priority
1.28 +// of the periodics.
1.29 +// - Create heartbeat timer with different priorities
1.30 +// - Start one heartbeat synchronized at ETwelveOClock
1.31 +// - Start two heartbeats synchronized at ETwelveOClock, ESixOClock
1.32 +// - Start three heartbeats synchronized at ETwelveOClock, ESixOClock, ETwelveOClock
1.33 +// - Display start time and beat time for each heartbeat timer
1.34 +// - Check if the heap has been corrupted by all the tests.
1.35 +// Platforms/Drives/Compatibility:
1.36 +// All.
1.37 +// Assumptions/Requirement/Pre-requisites:
1.38 +// Failures and causes:
1.39 +// - The first part of the test (for CPeriodic) will fail if the timers are not completed in order.
1.40 +// The test on emulator is very sensitive on the background activities on PC.
1.41 +// Base Port information:
1.42 +//
1.43 +//
1.44 +
1.45 +#include <e32base.h>
1.46 +#include <e32base_private.h>
1.47 +#include <e32hal.h>
1.48 +#include <e32test.h>
1.49 +#include <hal.h>
1.50 +#include <u32hal.h>
1.51 +#include <e32svr.h>
1.52 +
1.53 +LOCAL_D RTest test(_L("T_CPER"));
1.54 +
1.55 +class myScheduler: public CActiveScheduler
1.56 + {
1.57 +public:
1.58 + virtual void Error(TInt anError) const;
1.59 + };
1.60 +
1.61 +void myScheduler::Error(TInt anError) const
1.62 +//
1.63 +// virtual error handler
1.64 +//
1.65 + {
1.66 + test.Panic(anError,_L("myScheduler::Error"));
1.67 + }
1.68 +
1.69 +TInt Array[11];
1.70 +TTime Times[11];
1.71 +TInt counter = 0;
1.72 +
1.73 +CPeriodic* pPer1;
1.74 +CPeriodic* pPer2;
1.75 +CPeriodic* pPer3;
1.76 +CPeriodic* pPer4;
1.77 +CPeriodic* pPer5;
1.78 +CPeriodic* pPer6;
1.79 +CPeriodic* pPer7;
1.80 +
1.81 +TInt CallBackFn(TAny* Ptr)
1.82 +//
1.83 +// Callback function used for all periodics
1.84 +// On calling Ptr is actually a TInt - the periodic Id
1.85 +//
1.86 + {
1.87 + if (counter < 11)
1.88 + {
1.89 + Array[counter] = (TInt)Ptr;
1.90 + Times[counter].HomeTime();
1.91 + counter++;
1.92 + }
1.93 + return(0);
1.94 + }
1.95 +
1.96 +TInt CallBackPanic(TAny* Ptr)
1.97 +//
1.98 +// Periodic should never get called
1.99 +//
1.100 + {
1.101 + test.Printf(_L(" PERIODIC %d HAS GONE OFF!\n"),(TInt)Ptr);
1.102 + test(EFalse);
1.103 + return(KErrGeneral);
1.104 + }
1.105 +
1.106 +class myTimer: public CTimer
1.107 + {
1.108 +public:
1.109 + myTimer(TInt aPriority);
1.110 + virtual void RunL();
1.111 + };
1.112 +
1.113 +myTimer::myTimer(TInt aPriority) : CTimer(aPriority)
1.114 +//
1.115 +// Constructor - Creates AND ADDS TO MYSCHEDULER
1.116 +//
1.117 + {
1.118 + ConstructL();
1.119 + myScheduler::Add(this);
1.120 + }
1.121 +
1.122 +void myTimer::RunL()
1.123 +//
1.124 +// The timer stops the scheduler
1.125 +//
1.126 + {
1.127 + myScheduler::Stop();
1.128 + test.Printf(_L(" Timer has stopped ActiveScheduler\n"));
1.129 + }
1.130 +
1.131 +
1.132 +//
1.133 +// CHeartbeat test code
1.134 +//
1.135 +class CTick : public CBase, public MBeating
1.136 + {
1.137 +public:
1.138 + virtual void Beat();
1.139 + virtual void Synchronize();
1.140 + void Display();
1.141 + TInt iTicks;
1.142 + TTime iStartTime;
1.143 + TTime iTimes[4];
1.144 + };
1.145 +void CTick::Beat()
1.146 + {
1.147 +
1.148 + test.Printf(_L("Tick\n"));
1.149 + iTimes[iTicks].HomeTime();
1.150 + if (++iTicks>=4)
1.151 + CActiveScheduler::Stop();
1.152 + }
1.153 +void CTick::Synchronize()
1.154 + {
1.155 +
1.156 + test.Printf(_L("Sync tick to system clock\n"));
1.157 + iStartTime.HomeTime();
1.158 + iTicks=0;
1.159 + }
1.160 +
1.161 +void PrintTime(const TDesC& aName, const TTime& aTime)
1.162 + {
1.163 + TDateTime dt(aTime.DateTime());
1.164 + test.Printf(_L("%S = %02d:%02d:%02d:%06d\n"),&aName,dt.Hour(),dt.Minute(),dt.Second(),dt.MicroSecond());
1.165 + }
1.166 +
1.167 +void CTick::Display()
1.168 + {
1.169 + PrintTime(_L("Start time"),iStartTime);
1.170 + TInt i;
1.171 + for (i=0; i<4; i++)
1.172 + {
1.173 + TBuf<16> name;
1.174 + name.Format(_L("Beat %d"),i);
1.175 + PrintTime(name,iTimes[i]);
1.176 + }
1.177 + }
1.178 +
1.179 +class CTock : public CTick
1.180 + {
1.181 +public:
1.182 + virtual void Beat();
1.183 + virtual void Synchronize();
1.184 + };
1.185 +
1.186 +void CTock::Beat()
1.187 + {
1.188 +
1.189 + iTimes[iTicks++].HomeTime();
1.190 + test.Printf(_L("Tock\n"));
1.191 + }
1.192 +
1.193 +void CTock::Synchronize()
1.194 + {
1.195 +
1.196 + test.Printf(_L("Sync tock to system clock\n"));
1.197 + iStartTime.HomeTime();
1.198 + iTicks=0;
1.199 + }
1.200 +
1.201 +class CBigTock : public CTick
1.202 + {
1.203 +public:
1.204 + virtual void Beat();
1.205 + virtual void Synchronize();
1.206 + };
1.207 +
1.208 +void CBigTock::Beat()
1.209 + {
1.210 +
1.211 + iTimes[iTicks++].HomeTime();
1.212 + test.Printf(_L("TOCK!\n"));
1.213 + }
1.214 +
1.215 +void CBigTock::Synchronize()
1.216 + {
1.217 +
1.218 + test.Printf(_L("Sync TOCK to system clock\n"));
1.219 + iStartTime.HomeTime();
1.220 + iTicks=0;
1.221 + }
1.222 +
1.223 +void testHeartbeat()
1.224 +//
1.225 +// Test CHeartBeat
1.226 +//
1.227 + {
1.228 +
1.229 + test.Start(_L("Test CHeartbeat timer"));
1.230 + CActiveScheduler *scheduler = new CActiveScheduler;
1.231 + CActiveScheduler::Install(scheduler);
1.232 +
1.233 + test.Next(_L("Create a beating object synchronised at ETwelveOClock"));
1.234 + CTick *tick=new CTick;
1.235 + CHeartbeat *pH=NULL;
1.236 + TRAPD(r, pH=CHeartbeat::NewL(EPriorityNormal));
1.237 + test(r==KErrNone);
1.238 + test.Next(_L("Run for 4 beats on the second"));
1.239 + pH->Start(ETwelveOClock, tick);
1.240 + CActiveScheduler::Start();
1.241 + pH->Cancel();
1.242 + tick->Display();
1.243 +
1.244 + User::After(1000000);
1.245 + test.Next(_L("Create another heartbeat synchronised at ESixOClock"));
1.246 + CHeartbeat *pH6=CHeartbeat::New(EPriorityNormal);
1.247 + CTock *tock=new CTock;
1.248 + test.Next(_L("Start both"));
1.249 + pH->Start(ETwelveOClock, tick);
1.250 + pH6->Start(ESixOClock, tock);
1.251 + CActiveScheduler::Start();
1.252 + tick->Display();
1.253 + tock->Display();
1.254 +
1.255 + pH->Cancel();
1.256 + pH6->Cancel();
1.257 + User::After(1000000);
1.258 + test.Next(_L("Create another beating object synchronised at ESixOClock with a higher priority"));
1.259 + CHeartbeat *pH2=CHeartbeat::New(EPriorityHigh);
1.260 + CBigTock *bigtock=new CBigTock;
1.261 + test.Next(_L("Start all"));
1.262 + pH->Start(ETwelveOClock, tick);
1.263 + pH6->Start(ESixOClock, tock);
1.264 + pH2->Start(ESixOClock, bigtock);
1.265 + CActiveScheduler::Start();
1.266 + pH->Cancel();
1.267 + pH2->Cancel();
1.268 + pH6->Cancel();
1.269 + tick->Display();
1.270 + tock->Display();
1.271 + bigtock->Display();
1.272 +
1.273 + delete pH;
1.274 + delete pH2;
1.275 + delete pH6;
1.276 + delete tock;
1.277 + delete tick;
1.278 + delete bigtock;
1.279 + delete scheduler;
1.280 + test.End();
1.281 + }
1.282 +
1.283 +void testLockSpec()
1.284 +//
1.285 +// test the operators defined for TTimerLockSpec
1.286 +//
1.287 + {
1.288 +/*
1.289 + test.Start(_L("Test pre fix operator ++"));
1.290 + TTimerLockSpec i=ETwelveOClock,k=EOneOClock,l;
1.291 + TInt j;
1.292 + for (j=0; j<30; j++)
1.293 + {
1.294 + ++k=EOneOClock;
1.295 + test(k==EOneOClock);
1.296 + k=i;
1.297 + l=++i;
1.298 + switch (k)
1.299 + {
1.300 + case EOneOClock:
1.301 + test(i==ETwoOClock);
1.302 + test(l==ETwoOClock);
1.303 + break;
1.304 + case ETwoOClock:
1.305 + test(i==EThreeOClock);
1.306 + test(l==EThreeOClock);
1.307 + break;
1.308 + case EThreeOClock:
1.309 + test(i==EFourOClock);
1.310 + test(l==EFourOClock);
1.311 + break;
1.312 + case EFourOClock:
1.313 + test(i==EFiveOClock);
1.314 + test(l==EFiveOClock);
1.315 + break;
1.316 + case EFiveOClock:
1.317 + test(i==ESixOClock);
1.318 + test(l==ESixOClock);
1.319 + break;
1.320 + case ESixOClock:
1.321 + test(i==ESevenOClock);
1.322 + test(l==ESevenOClock);
1.323 + break;
1.324 + case ESevenOClock:
1.325 + test(i==EEightOClock);
1.326 + test(l==EEightOClock);
1.327 + break;
1.328 + case EEightOClock:
1.329 + test(i==ENineOClock);
1.330 + test(l==ENineOClock);
1.331 + break;
1.332 + case ENineOClock:
1.333 + test(i==ETenOClock);
1.334 + test(l==ETenOClock);
1.335 + break;
1.336 + case ETenOClock:
1.337 + test(i==EElevenOClock);
1.338 + test(l==EElevenOClock);
1.339 + break;
1.340 + case EElevenOClock:
1.341 + test(i==ETwelveOClock);
1.342 + test(l==ETwelveOClock);
1.343 + break;
1.344 + case ETwelveOClock:
1.345 + test(i==EOneOClock);
1.346 + test(l==EOneOClock);
1.347 + break;
1.348 + }
1.349 + }
1.350 +
1.351 + test.Next(_L("Test post fix operator ++"));
1.352 + for (j=0; j<30; j++)
1.353 + {
1.354 + ++k=EOneOClock;
1.355 + test(k==EOneOClock);
1.356 + k=i;
1.357 + l=i++;
1.358 + switch (k)
1.359 + {
1.360 + case EOneOClock:
1.361 + test(i==ETwoOClock);
1.362 + test(l==k);
1.363 + break;
1.364 + case ETwoOClock:
1.365 + test(i==EThreeOClock);
1.366 + test(l==k);
1.367 + break;
1.368 + case EThreeOClock:
1.369 + test(i==EFourOClock);
1.370 + test(l==k);
1.371 + break;
1.372 + case EFourOClock:
1.373 + test(i==EFiveOClock);
1.374 + test(l==k);
1.375 + break;
1.376 + case EFiveOClock:
1.377 + test(i==ESixOClock);
1.378 + test(l==k);
1.379 + break;
1.380 + case ESixOClock:
1.381 + test(i==ESevenOClock);
1.382 + test(l==k);
1.383 + break;
1.384 + case ESevenOClock:
1.385 + test(i==EEightOClock);
1.386 + test(l==k);
1.387 + break;
1.388 + case EEightOClock:
1.389 + test(i==ENineOClock);
1.390 + test(l==k);
1.391 + break;
1.392 + case ENineOClock:
1.393 + test(i==ETenOClock);
1.394 + test(l==k);
1.395 + break;
1.396 + case ETenOClock:
1.397 + test(i==EElevenOClock);
1.398 + test(l==k);
1.399 + break;
1.400 + case EElevenOClock:
1.401 + test(i==ETwelveOClock);
1.402 + test(l==k);
1.403 + break;
1.404 + case ETwelveOClock:
1.405 + test(i==EOneOClock);
1.406 + test(l==k);
1.407 + break;
1.408 + }
1.409 + }
1.410 + test.End();
1.411 +*/
1.412 + }
1.413 +
1.414 +
1.415 +GLDEF_C TInt E32Main()
1.416 + {
1.417 +
1.418 + test.Title();
1.419 + __UHEAP_MARK;
1.420 + test.Start(_L("Create some CPeriodics"));
1.421 +
1.422 + myScheduler* pScheduler = new myScheduler;
1.423 + myScheduler::Install(pScheduler);
1.424 +
1.425 + pPer1 = CPeriodic::New(0);
1.426 + pPer2 = CPeriodic::NewL(0);
1.427 + pPer3 = CPeriodic::NewL(10);
1.428 + pPer4 = CPeriodic::NewL(100);
1.429 + pPer5 = CPeriodic::NewL(100);
1.430 + pPer6 = CPeriodic::NewL(100);
1.431 + pPer7 = CPeriodic::NewL(100);
1.432 + myTimer* pTimer = new myTimer(50);
1.433 +
1.434 + test.Next(_L("Start them"));
1.435 +
1.436 + TCallBack callBack1(CallBackFn,(TAny*)1);
1.437 + TCallBack callBack2(CallBackFn,(TAny*)2);
1.438 + TCallBack callBack3(CallBackFn,(TAny*)3);
1.439 + TCallBack callBack4(CallBackPanic,(TAny*)4);
1.440 + TCallBack callBack5(CallBackPanic,(TAny*)5);
1.441 + TCallBack callBack6(CallBackPanic,(TAny*)6);
1.442 + TCallBack callBack7(CallBackPanic,(TAny*)7);
1.443 +
1.444 + TInt p=0;
1.445 + HAL::Get(HAL::ESystemTickPeriod, p);
1.446 +
1.447 + User::After(p); // ensure tick does not occur while starting all these timers
1.448 +
1.449 + pPer1->Start(2*p+1,7*p+1,callBack1); //After 3 ticks, complete every 8th tick
1.450 + pPer2->Start(1, 2*p+1,callBack2); //After 1 tick , complete every 3rd tick
1.451 + pPer3->Start(7*p+1, p+1,callBack3); //After 8 ticks, complete every 2nd tick
1.452 +
1.453 + pPer4->Start(KMaxTInt,KMaxTInt,callBack4);
1.454 + pPer5->Start(60000000,60000000,callBack5);
1.455 + pPer6->Start(KMaxTInt/91,KMaxTInt/91,callBack6);
1.456 + pPer7->Start(KMaxTInt/91+1,KMaxTInt/91+1,callBack7);
1.457 + pTimer->After(20*p-1); // ensure there's enough time for them to fill up the array.
1.458 + /*
1.459 + Time per1 per2 per3
1.460 + 1 -
1.461 + 2
1.462 + 3 -
1.463 + 4 -
1.464 + 5
1.465 + 6
1.466 + 7 -
1.467 + 8 -
1.468 + 9
1.469 + 10 - -
1.470 + 11 -
1.471 + 12 -
1.472 + 13 -
1.473 + 14 -
1.474 + */
1.475 +
1.476 + myScheduler::Start();
1.477 +
1.478 + TInt i;
1.479 + for (i=0; i<counter; ++i)
1.480 + {
1.481 + test.Printf(_L(" Time: %7d Periodic: %d\n"),static_cast<TUint32>(Times[i].Int64()-Times[0].Int64()),Array[i]);
1.482 + }
1.483 +
1.484 + test(Array[0]==2);
1.485 + test(Array[1]==1);
1.486 + test(Array[2]==2);
1.487 + test(Array[3]==2);
1.488 + test(Array[4]==3);
1.489 + TBool normal56 = (Array[5]==3 && Array[6]==2);
1.490 + TBool reverse56 = (Array[5]==2 && Array[6]==3);
1.491 + if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1)
1.492 + {
1.493 + // If there are multiple processors the order of 'simultaneous' timers is undefined since
1.494 + // the test may get to run as soon as the first timer is completed, instead of only after
1.495 + // the timer thread blocks, which would be after both timers completed.
1.496 + test(normal56 || reverse56);
1.497 + }
1.498 + else
1.499 + test(normal56);
1.500 + test(Array[7]==1);
1.501 + test(Array[8]==3);
1.502 + test(Array[9]==2);
1.503 + test(Array[10]==3);
1.504 +
1.505 + test.Next(_L("Destroy them"));
1.506 +
1.507 + delete pPer1;
1.508 + delete pPer2;
1.509 + delete pPer3;
1.510 + delete pPer4;
1.511 + delete pPer5;
1.512 + delete pPer6;
1.513 + delete pPer7;
1.514 + delete pTimer;
1.515 + delete pScheduler;
1.516 +
1.517 + test.Next(_L("Test CHeartbeat"));
1.518 + testHeartbeat();
1.519 + test.Next(_L("Test TTimerLockSpec"));
1.520 + testLockSpec();
1.521 + __UHEAP_MARKEND;
1.522 + test.End();
1.523 + return(KErrNone);
1.524 + }