1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/euser/cbase/ub_tim.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,539 @@
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 +// e32\euser\cbase\ub_tim.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "ub_std.h"
1.22 +
1.23 +EXPORT_C CTimer::CTimer(TInt aPriority)
1.24 + : CActive(aPriority)
1.25 +/**
1.26 +Protected constructor with priority.
1.27 +
1.28 +Use this constructor to set the priority of the active object.
1.29 +
1.30 +Classes derived from CTimer must define and provide a constructor through
1.31 +which the priority of the active object can be passed. Such a constructor
1.32 +can call CTimer's constructor in its constructor initialisation list.
1.33 +
1.34 +@param aPriority The priority of the timer.
1.35 +*/
1.36 + {
1.37 + }
1.38 +
1.39 +
1.40 +
1.41 +
1.42 +EXPORT_C CTimer::~CTimer()
1.43 +/**
1.44 +Destructor.
1.45 +
1.46 +Frees resources prior to destruction. Specifically, it cancels any outstanding
1.47 +request and closes the RTimer handle.
1.48 +*/
1.49 + {
1.50 +
1.51 + Cancel();
1.52 + iTimer.Close();
1.53 + }
1.54 +
1.55 +
1.56 +
1.57 +
1.58 +EXPORT_C void CTimer::At(const TTime &aTime)
1.59 +/**
1.60 +Requests an event at a given local time.
1.61 +
1.62 +This timer completes at the specified time - if the machine is in a
1.63 +turned off state at that time, the machine will be turned on again.
1.64 +
1.65 +Notes:
1.66 +
1.67 +1. The CTimer' RunL() function will be run as soon as possible after the
1.68 + specified system time.
1.69 +
1.70 +2. The RunL() may be delayed because the RunL() of another active object, with
1.71 + the deepest nesting-level active scheduler on the same thread, is running
1.72 + when the event occurs: this cannot be avoided, but can be minimised by
1.73 + making all RunL()s of short duration.
1.74 +
1.75 +3. The RunL() may be delayed because other, higher-priority, active objects are
1.76 + scheduled instead. This can be avoided by making CTimers very high-priority.
1.77 +
1.78 +4. The TTime object should be set to the home time.
1.79 +
1.80 +@param aTime The local time at which the event is to occur.
1.81 +
1.82 +@see TTime::HomeTime
1.83 +*/
1.84 + {
1.85 +
1.86 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.87 + iTimer.At(iStatus,aTime);
1.88 + SetActive();
1.89 + }
1.90 +
1.91 +
1.92 +
1.93 +
1.94 +EXPORT_C void CTimer::AtUTC(const TTime &aTimeInUTC)
1.95 +/**
1.96 +Requests an event at a given UTC time.
1.97 +
1.98 +This timer completes at the specified time - if the machine is in a
1.99 +turned off state at that time, the machine will be turned on again.
1.100 +
1.101 +Notes:
1.102 +
1.103 +1. The CTimer' RunL() function will be run as soon as possible after the
1.104 + specified system time.
1.105 +
1.106 +2. The RunL() may be delayed because the RunL() of another active object, with
1.107 + the deepest nesting-level active scheduler on the same thread, is running
1.108 + when the event occurs: this cannot be avoided, but can be minimised by
1.109 + making all RunL()s of short duration.
1.110 +
1.111 +3. The RunL() may be delayed because other, higher-priority, active objects are
1.112 + scheduled instead. This can be avoided by making CTimers very high-priority.
1.113 +
1.114 +4. The TTime object should be set to the universal time.
1.115 +
1.116 +@param aTime The UTC time at which the event is to occur.
1.117 +
1.118 +@see TTime::UniversalTime
1.119 +*/
1.120 + {
1.121 +
1.122 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.123 + iTimer.AtUTC(iStatus,aTimeInUTC);
1.124 + SetActive();
1.125 + }
1.126 +
1.127 +
1.128 +
1.129 +
1.130 +EXPORT_C void CTimer::After(TTimeIntervalMicroSeconds32 anInterval)
1.131 +/**
1.132 +Requests an event after an interval.
1.133 +
1.134 +This timer completes after the specified number of microseconds. The
1.135 +"after timer" counter stops during power-down. Therefore, a 5-second timer
1.136 +will complete late if the machine is turned off 2 seconds after the request
1.137 +is made.
1.138 +
1.139 +Notes:
1.140 +
1.141 +1. The CTimer's RunL() function will be run as soon as possible after the
1.142 + specified interval.
1.143 +
1.144 +2. The RunL() may be delayed because the RunL() of another active object, with
1.145 + the deepest nesting-level active scheduler on the same thread, is running
1.146 + when the event occurs: this cannot be avoided, but can be minimised by
1.147 + making all RunL()s of short duration.
1.148 +
1.149 +3. The RunL() may be delayed because other, higher-priority, active objects are
1.150 + scheduled instead. This can be avoided by making CTimers very high-priority.
1.151 +
1.152 +@param anInterval Interval after which event is to occur, in microseconds.
1.153 +
1.154 +@panic USER 87, if anInterval is negative. This is raised by the
1.155 + underlying RTimer.
1.156 +@panic E32USER-CBase 51, if the active object has not been added to an
1.157 + active scheduler.
1.158 +
1.159 +@see RTimer
1.160 +*/
1.161 + {
1.162 +
1.163 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.164 + iTimer.After(iStatus,anInterval);
1.165 + SetActive();
1.166 + }
1.167 +
1.168 +
1.169 +
1.170 +
1.171 +EXPORT_C void CTimer::Lock(TTimerLockSpec aLock)
1.172 +/**
1.173 +Requests an event on a specified second fraction.
1.174 +
1.175 +Note that the RunL() function is run exactly on the specified second fraction.
1.176 +
1.177 +@param aLock The fraction of a second at which the timer completes.
1.178 +*/
1.179 + {
1.180 +
1.181 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.182 + iTimer.Lock(iStatus,aLock);
1.183 + SetActive();
1.184 + }
1.185 +
1.186 +
1.187 +
1.188 +
1.189 +EXPORT_C void CTimer::Inactivity(TTimeIntervalSeconds aSeconds)
1.190 +/**
1.191 +Requests an event if no activity occurs within the specified interval.
1.192 +
1.193 +@param aSeconds The time interval.
1.194 +*/
1.195 + {
1.196 +
1.197 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.198 + iTimer.Inactivity(iStatus, aSeconds);
1.199 + SetActive();
1.200 + }
1.201 +
1.202 +
1.203 +
1.204 +EXPORT_C void CTimer::HighRes(TTimeIntervalMicroSeconds32 aInterval)
1.205 +/**
1.206 +Requests an event after the specified interval to a resolution of 1ms.
1.207 +The "HighRes timer" counter stops during power-down (the same as "after timer").
1.208 +
1.209 +@param aInterval The time interval, in microseconds, after which an event
1.210 + is to occur.
1.211 +@panic USER 87, if anInterval is negative. This is raised by the
1.212 + underlying RTimer.
1.213 +@panic KERN-EXEC 15, if this function is called while a request for a timer
1.214 + event is still outstanding.
1.215 +*/
1.216 + {
1.217 +
1.218 + __ASSERT_ALWAYS(IsAdded(),Panic(ETimNotAdded));
1.219 + iTimer.HighRes(iStatus, aInterval);
1.220 + SetActive();
1.221 + }
1.222 +
1.223 +
1.224 +
1.225 +
1.226 +EXPORT_C void CTimer::ConstructL()
1.227 +/**
1.228 +Constructs a new asynchronous timer.
1.229 +
1.230 +The function must be called before any timer requests (i.e. calls to
1.231 +RTimer::After() or RTimer::At()) can be made.
1.232 +
1.233 +Since it is protected, it cannot be called directly by clients of CTimer
1.234 +derived classes. Typically, a derived class makes a base call to this function
1.235 +in the second phase of two-phase construction; i.e. the derived class defines
1.236 +and implements its own ConstructL() function within which it makes a base
1.237 +call to CTimer::ConstructL().
1.238 +*/
1.239 + {
1.240 +
1.241 + TInt r=iTimer.CreateLocal();
1.242 + if (r!=KErrNone)
1.243 + User::Leave(r);
1.244 + }
1.245 +
1.246 +
1.247 +
1.248 +
1.249 +EXPORT_C void CTimer::DoCancel()
1.250 +//
1.251 +// Cancel the timer.
1.252 +//
1.253 + {
1.254 +
1.255 + iTimer.Cancel();
1.256 + }
1.257 +
1.258 +
1.259 +
1.260 +
1.261 +EXPORT_C CPeriodic *CPeriodic::New(TInt aPriority)
1.262 +/**
1.263 +Allocates and constructs a CPeriodic object - non-leaving.
1.264 +
1.265 +Specify a high priority so the callback function is scheduled as soon as
1.266 +possible after the timer events complete.
1.267 +
1.268 +@param aPriority The priority of the active object. If timing is critical,
1.269 + it should be higher than that of all other active objects
1.270 + owned by the scheduler.
1.271 +
1.272 +@return Pointer to new CPeriodic object. The object is initialised and added
1.273 + to the active scheduler. This value is NULL if there is insufficient
1.274 + memory.
1.275 +*/
1.276 + {
1.277 +
1.278 + CPeriodic *pP=new CPeriodic(aPriority);
1.279 + if (pP)
1.280 + {
1.281 + TRAPD(r,pP->ConstructL());
1.282 + if (r==KErrNone)
1.283 + CActiveScheduler::Add(pP);
1.284 + else
1.285 + {
1.286 + delete pP;
1.287 + pP=NULL;
1.288 + }
1.289 + }
1.290 + return pP;
1.291 + }
1.292 +
1.293 +
1.294 +
1.295 +
1.296 +EXPORT_C CPeriodic *CPeriodic::NewL(TInt aPriority)
1.297 +/**
1.298 +Allocates and constructs a CPeriodic object - leaving.
1.299 +
1.300 +Specify a high priority so the callback function is scheduled as soon as
1.301 +possible after the timer events complete.
1.302 +
1.303 +@param aPriority The priority of the active object. If timing is critical,
1.304 + it should be higher than that of all other active objects
1.305 + owned by the scheduler.
1.306 +
1.307 +@return Pointer to new CPeriodic object. The object is initialised and added
1.308 + to the active scheduler.
1.309 +
1.310 +@leave KErrNoMemory There is insufficient memory to create the object.
1.311 +*/
1.312 + {
1.313 +
1.314 + return((CPeriodic *)User::LeaveIfNull(New(aPriority)));
1.315 + }
1.316 +
1.317 +
1.318 +
1.319 +
1.320 +EXPORT_C CPeriodic::CPeriodic(TInt aPriority)
1.321 + : CTimer(aPriority)
1.322 +/**
1.323 +Protected constructor with priority.
1.324 +
1.325 +Use this constructor to set the priority of the active object.
1.326 +
1.327 +Classes derived from CPeriodic must define and provide a constructor through
1.328 +which the priority of the active object can be passed. Such a constructor
1.329 +can call CPeriodic's constructor in its constructor initialisation list.
1.330 +
1.331 +@param aPriority The priority of the timer.
1.332 +*/
1.333 + {
1.334 + }
1.335 +
1.336 +
1.337 +
1.338 +
1.339 +EXPORT_C CPeriodic::~CPeriodic()
1.340 +/**
1.341 +Destructor.
1.342 +
1.343 +Frees resources prior to destruction.
1.344 +*/
1.345 + {
1.346 + }
1.347 +
1.348 +
1.349 +
1.350 +
1.351 +EXPORT_C void CPeriodic::Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32 anInterval,TCallBack aCallBack)
1.352 +/**
1.353 +Starts generating periodic events.
1.354 +
1.355 +The event calls the protected RunL() function,
1.356 +which in turn calls the function specified by aCallBack. The first event is
1.357 +generated after aDelay microseconds; subsequent events are generated regularly
1.358 +thereafter at intervals of anInterval microseconds.
1.359 +
1.360 +The TCallBack contains a function pointer and a TAny* pointer. The function
1.361 +will be repeatedly called with the pointer as a parameter.
1.362 +
1.363 +Once started, periodic events are generated until the CPeriodic object is
1.364 +destroyed.
1.365 +
1.366 +Notes:
1.367 +
1.368 +1. The callback function will be run as soon as possible after the initial delay,
1.369 + and after each period.
1.370 +
1.371 +2. The callback may be delayed because the RunL() of another active object, with
1.372 + the deepest nesting-level active scheduler on the same thread, is running
1.373 + when the event occurs: this cannot be avoided, but can be minimised by making
1.374 + all RunL()s of short duration.
1.375 +
1.376 +3. The callback may be delayed because other, higher-priority, active objects
1.377 + are scheduled instead. This can be avoided by giving the CPeriodic a very
1.378 + high priority.
1.379 +
1.380 +@param aDelay The delay from the Start() function to the generation of the
1.381 + first event, in microseconds.
1.382 +@param anInterval The interval between events generated after the initial
1.383 + delay, in microseconds.
1.384 +@param aCallBack A callback specifying a function to be called when the CPeriodic
1.385 + is scheduled after a timer event.
1.386 +
1.387 +@panic E32USER-CBase 52, if anInterval is negative.
1.388 +@panic E32USER-CBase 53, if aDelay is negative.
1.389 +*/
1.390 + {
1.391 +
1.392 + __ASSERT_ALWAYS(anInterval.Int()>=0,Panic(ETimIntervalNegativeOrZero));
1.393 + __ASSERT_ALWAYS(aDelay.Int()>=0,Panic(ETimDelayNegative));
1.394 + iInterval=anInterval.Int();
1.395 + iCallBack=aCallBack;
1.396 + After(aDelay);
1.397 + }
1.398 +
1.399 +EXPORT_C void CPeriodic::RunL()
1.400 +//
1.401 +// Handle completion by issuing the next request and then calling back.
1.402 +//
1.403 + {
1.404 +
1.405 + After(iInterval);
1.406 + iCallBack.CallBack();
1.407 + }
1.408 +
1.409 +
1.410 +
1.411 +
1.412 +EXPORT_C CHeartbeat::CHeartbeat(TInt aPriority)
1.413 + : CTimer(aPriority)
1.414 +/**
1.415 +Protected constructor with a priority. Use this constructor to set the priority
1.416 +of the active object.
1.417 +
1.418 +Classes derived from CHeartbeat must define and provide a constructor through
1.419 +which the priority of the active object can be passed. Such a constructor
1.420 +can call CHeartbeat's constructor in its constructor initialisation list.
1.421 +
1.422 +@param aPriority The priority of the timer.
1.423 +*/
1.424 + {}
1.425 +
1.426 +
1.427 +
1.428 +
1.429 +EXPORT_C CHeartbeat *CHeartbeat::New(TInt aPriority)
1.430 +/**
1.431 +Allocates and constructs a CHeartbeat object - non-leaving.
1.432 +
1.433 +Specify a high priority so the callback function is scheduled as soon as
1.434 +possible after the timer events complete.
1.435 +
1.436 +@param aPriority The priority of the active object. If timing is critical,
1.437 + it should be higher than that of all other active objects
1.438 + owned by the scheduler.
1.439 +
1.440 +@return Pointer to new CHeartbeat object. The object is initialised and added
1.441 + to the active scheduler. This value is NULL if insufficient memory was
1.442 + available.
1.443 +*/
1.444 + {
1.445 +
1.446 + CHeartbeat *pP=new CHeartbeat(aPriority);
1.447 + if (pP)
1.448 + {
1.449 + TRAPD(r,pP->ConstructL());
1.450 + if (r==KErrNone)
1.451 + CActiveScheduler::Add(pP);
1.452 + else
1.453 + {
1.454 + delete pP;
1.455 + pP=NULL;
1.456 + }
1.457 + }
1.458 + return pP;
1.459 + }
1.460 +
1.461 +
1.462 +
1.463 +
1.464 +EXPORT_C CHeartbeat *CHeartbeat::NewL(TInt aPriority)
1.465 +/**
1.466 +Allocates and constructs a CHeartbeat object - leaving.
1.467 +
1.468 +Specify a high priority so the callback function is scheduled as soon as
1.469 +possible after the timer events complete.
1.470 +
1.471 +@param aPriority The priority of the active object. If timing is critical,
1.472 + it should be higher than that of all other active objects
1.473 + owned by the scheduler.
1.474 +
1.475 +@return Pointer to new CHeartbeat object. The object is initialised and added
1.476 + to the active scheduler.
1.477 +*/
1.478 + {
1.479 +
1.480 + return((CHeartbeat *)User::LeaveIfNull(New(aPriority)));
1.481 + }
1.482 +
1.483 +
1.484 +
1.485 +
1.486 +EXPORT_C CHeartbeat::~CHeartbeat()
1.487 +/**
1.488 +Destructor.
1.489 +
1.490 +Frees resources prior to destruction.
1.491 +*/
1.492 + {}
1.493 +
1.494 +
1.495 +
1.496 +
1.497 +EXPORT_C void CHeartbeat::Start(TTimerLockSpec aLock, MBeating *aBeating)
1.498 +/**
1.499 +Starts generating heartbeat events. The event results in calls to the Beat()
1.500 +and Synchronize() functions specified by aBeating.
1.501 +
1.502 +The first event is generated on the first fraction of a second corresponding
1.503 +to aLock that occurs after Start() has returned; subsequent events are generated
1.504 +regularly thereafter at one second intervals on the second fraction specified
1.505 +by aLock.
1.506 +
1.507 +The aBeating mixin must be written by the user. Most of the time, its Beat()
1.508 +function is called which trivially updates the tick count. Occasionally, synchronisation
1.509 +is lost, and the Synchronize() function is called instead: this must find
1.510 +out from the system time how many ticks should have been counted, and update
1.511 +things accordingly.
1.512 +
1.513 +Once started, heartbeat events are generated until the CHeartbeat object is
1.514 +destroyed.
1.515 +
1.516 +@param aLock The fraction of a second at which the timer completes.
1.517 +@param aBeating Provides the Beat() and Synchronize() functions.
1.518 +*/
1.519 + {
1.520 +
1.521 + iBeating=aBeating;
1.522 + iLock=aLock;
1.523 + Lock(aLock);
1.524 + }
1.525 +
1.526 +
1.527 +
1.528 +
1.529 +EXPORT_C void CHeartbeat::RunL()
1.530 +//
1.531 +// Handle completion
1.532 +//
1.533 + {
1.534 +
1.535 + TRequestStatus stat=iStatus;
1.536 + Lock(iLock);
1.537 + if (stat==KErrNone)
1.538 + iBeating->Beat();
1.539 + else
1.540 + iBeating->Synchronize();
1.541 + }
1.542 +