00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "CommonFramework.h"
00049
00050
00051
00052 #include <e32math.h>
00053
00054 void RandomDelay(TInt64& aSeed, TInt )
00055 {
00056
00057 if (aSeed==0)
00058 {
00059 TTime time;
00060 time.HomeTime();
00061 aSeed=time.Int64();
00062 }
00063
00064 TReal randomZeroToOne;
00065 randomZeroToOne = Math::FRand(aSeed);
00066 TReal realDelay;
00067 realDelay = randomZeroToOne * randomZeroToOne * 2000000;
00068 TInt32 intDelay;
00069 Math::Int(intDelay, realDelay);
00070 TTimeIntervalMicroSeconds32 delayMicroSeconds;
00071 delayMicroSeconds=intDelay;
00072 User::After(delayMicroSeconds);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 class TAppRunner
00089 {
00090 public:
00091 TAppRunner();
00092 void NotifyFinished();
00093 void NotifyStarted();
00094
00095 TInt iActiveObjects;
00096 };
00097
00098 TAppRunner::TAppRunner()
00099 {
00100 iActiveObjects=0;
00101 }
00102
00103 void TAppRunner::NotifyStarted()
00104 {
00105 iActiveObjects++;
00106 }
00107
00108 void TAppRunner::NotifyFinished()
00109 {
00110 iActiveObjects--;
00111 if (iActiveObjects==0) CActiveScheduler::Stop();
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 class CPeriodicRunner : public CBase
00128 {
00129 public:
00130
00131 static CPeriodicRunner* NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
00132 ~CPeriodicRunner();
00133 protected:
00134 CPeriodicRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
00135 private:
00136 void ConstructL();
00137
00138 static TInt Tick(TAny* aObject);
00139 void DoTick();
00140 private:
00141
00142 TAppRunner& iAppRunner;
00143 TInt iTotalTicks;
00144 TInt iTickInterval;
00145
00146
00147 TTime iStartTime;
00148 CPeriodic* iPeriodic;
00149
00150
00151 TInt iTicksLeft;
00152 TInt iTimerNumber;
00153
00154
00155 TInt64 iDelaySeed;
00156 };
00157
00158
00159 CPeriodicRunner::CPeriodicRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
00160 : iAppRunner(aAppRunner), iTotalTicks(aTotalTicks), iTickInterval(aTickInterval)
00161 {}
00162
00163
00164 void CPeriodicRunner::ConstructL()
00165 {
00166 iStartTime.HomeTime();
00167 iPeriodic =CPeriodic::NewL(0);
00168 iAppRunner.NotifyStarted();
00169 iTimerNumber = iAppRunner.iActiveObjects;
00170 iTicksLeft = iTotalTicks;
00171
00172 iPeriodic->Start(iTickInterval,iTickInterval,TCallBack(Tick, this));
00173 }
00174
00175
00176 CPeriodicRunner* CPeriodicRunner::NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
00177 {
00178 CPeriodicRunner* self=new (ELeave) CPeriodicRunner(aTickInterval, aTotalTicks, aAppRunner);
00179 CleanupStack::PushL(self);
00180 self->ConstructL();
00181 CleanupStack::Pop();
00182 return self;
00183 }
00184
00185
00186 CPeriodicRunner::~CPeriodicRunner()
00187 {
00188 TTimeIntervalMicroSeconds elapsedTime;
00189 TTime currentTime;
00190
00191 currentTime.HomeTime();
00192
00193 elapsedTime = currentTime.MicroSecondsFrom(iStartTime);
00194
00195 _LIT(KFormat1,"Periodic timer %d finished after: %Ld microseconds for %d %dus ticks\n");
00196 console->Printf(KFormat1,iTimerNumber,elapsedTime.Int64(),iTotalTicks,iTickInterval);
00197
00198
00199
00200
00201 iPeriodic->Cancel();
00202 delete iPeriodic;
00203
00204 iAppRunner.NotifyFinished();
00205 }
00206
00207
00208 TInt CPeriodicRunner::Tick(TAny* aObject)
00209 {
00210 ((CPeriodicRunner*)aObject)->DoTick();
00211 return 1;
00212 }
00213
00214
00215 void CPeriodicRunner::DoTick()
00216 {
00217 iTicksLeft--;
00218 _LIT(KFormat2,"Periodic timer %d: %d ticks done\n");
00219 console->Printf(KFormat2, iTimerNumber, iTotalTicks - iTicksLeft);
00220 if(iTicksLeft==0)
00221 {
00222 delete this;
00223 }
00224 RandomDelay(iDelaySeed,iTimerNumber);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 class CHeartbeatRunner : public CBase, public MBeating
00245 {
00246 public:
00247
00248 static CHeartbeatRunner* NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
00249 ~CHeartbeatRunner();
00250 protected:
00251 CHeartbeatRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner);
00252 private:
00253 void ConstructL();
00254
00255 void Beat();
00256 void Synchronize();
00257 private:
00258
00259 TAppRunner& iAppRunner;
00260 TInt iTotalTicks;
00261 TInt iTickInterval;
00262
00263 TTime iStartTime;
00264 CHeartbeat* iHeartbeat;
00265
00266 TInt iTicksLeft;
00267 TInt iTimerNumber;
00268
00269 TInt64 iDelaySeed;
00270 };
00271
00272
00273 CHeartbeatRunner::CHeartbeatRunner(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
00274 :iAppRunner(aAppRunner), iTotalTicks(aTotalTicks), iTickInterval(aTickInterval)
00275 {}
00276
00277
00278 void CHeartbeatRunner::ConstructL()
00279 {
00280 iStartTime.HomeTime();
00281 iHeartbeat=CHeartbeat::NewL(0);
00282 iAppRunner.NotifyStarted();
00283 iTimerNumber = iAppRunner.iActiveObjects;
00284 iTicksLeft = iTotalTicks;
00285
00286 iHeartbeat->Start(ETwelveOClock,this);
00287 }
00288
00289
00290 CHeartbeatRunner* CHeartbeatRunner::NewL(TInt aTickInterval, TInt aTotalTicks, TAppRunner& aAppRunner)
00291 {
00292 CHeartbeatRunner* self=new (ELeave) CHeartbeatRunner(aTickInterval, aTotalTicks, aAppRunner);
00293 CleanupStack::PushL(self);
00294 self->ConstructL();
00295 CleanupStack::Pop();
00296 return self;
00297 }
00298
00299
00300 CHeartbeatRunner::~CHeartbeatRunner()
00301 {
00302 TTimeIntervalMicroSeconds elapsedTime;
00303 TTime currentTime;
00304 currentTime.HomeTime();
00305
00306 elapsedTime = currentTime.MicroSecondsFrom(iStartTime);
00307
00308 _LIT(KFormat3,"Heartbeat timer %d finished after: %Ld microseonds for %d %dus ticks\n");
00309 console->Printf(KFormat3,iTimerNumber,elapsedTime.Int64(),iTotalTicks,iTickInterval);
00310
00311
00312 iHeartbeat->Cancel();
00313 delete iHeartbeat;
00314
00315 iAppRunner.NotifyFinished();
00316 }
00317
00318
00319 void CHeartbeatRunner::Beat()
00320 {
00321 iTicksLeft--;
00322 if(iTicksLeft<=0)
00323 delete this;
00324 else
00325 RandomDelay(iDelaySeed,iTimerNumber);
00326 }
00327
00328
00329 void CHeartbeatRunner::Synchronize()
00330 {
00331 TInt ticksMissed = 0;
00332
00333 TTime desiredTime = iStartTime + TTimeIntervalMicroSeconds((iTotalTicks - iTicksLeft) * iTickInterval);
00334 TTime currentTime;
00335 currentTime.HomeTime();
00336 TTimeIntervalMicroSeconds missedTime = currentTime.MicroSecondsFrom(desiredTime);
00337
00338 TInt64 missedTimeInt = missedTime.Int64();
00339
00340 ticksMissed = (missedTimeInt / iTickInterval);
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 _LIT(KFormat4,"Ticks done %d\n");
00351 console->Printf(KFormat4, (iTotalTicks -iTicksLeft));
00352
00353 iTicksLeft = iTicksLeft - ticksMissed;
00354 TTimeIntervalMicroSeconds elapsedTime;
00355 elapsedTime = currentTime.MicroSecondsFrom(iStartTime);
00356 _LIT(KFormat5,"Elapsed time: %Ld microseconds\n");
00357 console->Printf(KFormat5, elapsedTime.Int64());
00358
00359 _LIT(KFormat6,"Synchronize heartbeat timer %d: ticks missed %d: left %d: done now %d\n");
00360 console->Printf(KFormat6,
00361 iTimerNumber,
00362 ticksMissed,
00363 iTicksLeft,
00364 ((iTotalTicks - iTicksLeft) <= iTotalTicks) ? iTotalTicks - iTicksLeft : iTotalTicks
00365 );
00366
00367 if(iTicksLeft<=0)
00368 {
00369 delete this;
00370 }
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 void doExampleL()
00383 {
00384
00385 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
00386
00387
00388 CleanupStack::PushL(scheduler);
00389
00390
00391 CActiveScheduler::Install(scheduler);
00392
00393
00394 TAppRunner appRunner;
00395
00396
00397 TInt TickInterval = 1000000;
00398
00399
00400
00401
00402 for (TInt total_ticks=4; total_ticks<=6; total_ticks+=2)
00403 {
00404
00405
00406
00407 CPeriodicRunner::NewL(TickInterval, total_ticks, appRunner);
00408
00409
00410
00411
00412 CHeartbeatRunner::NewL(TickInterval, total_ticks, appRunner);
00413 }
00414
00415 CActiveScheduler::Start();
00416 CleanupStack::PopAndDestroy();
00417 }
00418