diff -r 05bc53fe583b -r 83ca720e2b9a keepalive/flextimer/server/engine/src/flextimercontainer.cpp --- a/keepalive/flextimer/server/engine/src/flextimercontainer.cpp Tue Aug 31 15:35:44 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,459 +0,0 @@ -/* - * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). - * All rights reserved. - * This component and the accompanying materials are made available - * under the terms of "Eclipse Public License v1.0" - * which accompanies this distribution, and is available - * at the URL "http://www.eclipse.org/legal/epl-v10.html". - * - * Initial Contributors: - * Nokia Corporation - Initial contribution - * - * Description: - * This class contains implementation of CFlexTimerContainer. - * - */ - -// System include files -#include - -// User include files -#include "flextimercommon.h" -#include "flextimercontainer.h" -#include "flextimeritem.h" -#include "mflextimerservicecb.h" -#include "OstTraceDefinitions.h" -#ifdef OST_TRACE_COMPILER_IN_USE -#include "flextimercontainerTraces.h" -#endif - - - -// This literal is only used by __ASSERT_DEBUG macro. Therefore, to prevent -// unnacessary warnings, it is not compiled into release builds. -#ifdef _DEBUG -static const TInt KCBNullPointer = 1; -_LIT( KCBNullPointerDescriptor, "FlexTimerService CB is NULL." ); -#endif - -// --------------------------------------------------------------------------- -// NewL -// --------------------------------------------------------------------------- -// -CFlexTimerContainer* CFlexTimerContainer::NewL() - { - CFlexTimerContainer* self = new (ELeave) CFlexTimerContainer(); - - OstTrace1( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_NEWL, - "CFlexTimerContainer::NewL;this=%x", - ( TUint )self ); - - return self; - } - -// --------------------------------------------------------------------------- -// destructor -// If the list is not empty when coming here something has already gone wrong. -// Lets just delete the timers and forget Timeout() calling -// --------------------------------------------------------------------------- -// -CFlexTimerContainer::~CFlexTimerContainer() - { - CFlexTimerItem* item = NULL; - - OstTrace1( - TRACE_INTERNAL, - DUP1_CFLEXTIMERCONTAINER_CFLEXTIMERCONTAINER, - "CFlexTimerContainer::~CFlexTimerContainer;this=%x", - ( TUint )this ); - - while ( !iTimerList.IsEmpty() ) - { - item = iTimerList.First(); - iTimerList.Remove( *item ); - delete item; - } - } -// --------------------------------------------------------------------------- -// Make new timer and add it to list. On purpose do not make sanity checks. -// Invalid(in the past) timers are found later. -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::AddTimerL( - const TTimeIntervalMicroSeconds& aWinStartInterval, - const TTimeIntervalMicroSeconds& aWinEndInterval, - TBool aCancelAtSystemTimeChange, - const MFlexTimerServiceCB* aFlexTimerServiceCB ) - { - OstTraceExt5( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_ADDTIMERL, - "CFlexTimerContainer::AddTimerL;this=%x;" - "aWinStartInterval=%Ld;" - "aWinEndInterval=%Ld;" - "aCancelAtSystemTimeChange=%u;" - "aFlexTimerServiceCB=%x", - ( TUint )this, - aWinStartInterval.Int64(), - aWinEndInterval.Int64(), - aCancelAtSystemTimeChange, - ( TUint )aFlexTimerServiceCB ); - - __ASSERT_DEBUG( aFlexTimerServiceCB, - User::Panic( KCBNullPointerDescriptor, KCBNullPointer ) ); - - // Before creating new flextimer timeout item, the interval times are - // converted to absolute tick based time used by the engine. - TTime winAbsStart( IntervalToAbsoluteTime( aWinStartInterval ) ); - TTime winAbsEnd( IntervalToAbsoluteTime( aWinEndInterval ) ); - - CFlexTimerItem* newItem = CFlexTimerItem::NewL( winAbsStart, - winAbsEnd, - aCancelAtSystemTimeChange, - aFlexTimerServiceCB ); - - iTimerList.AddLast( *newItem ); - } -// --------------------------------------------------------------------------- -// Loop through list and if timer containing same CB that is given as a -// parameter is found, remove timer. If no timer found just return error code. -// --------------------------------------------------------------------------- -// -TInt CFlexTimerContainer::RemoveTimer( - const MFlexTimerServiceCB* aFlexTimerServiceCB ) - { - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_REMOVETIMER, - "CFlexTimerContainer::RemoveTimer;this=%x;aFlexTimerServiceCB=%x", - ( TUint )this, - ( TUint )aFlexTimerServiceCB ); - - __ASSERT_DEBUG( aFlexTimerServiceCB, - User::Panic( KCBNullPointerDescriptor, KCBNullPointer ) ); - - TSglQueIter listIter( iTimerList ); - CFlexTimerItem* item = NULL; - - listIter.SetToFirst(); - // Iter++ makes iterator to point to next element if one exists. - // Otherwise NULL. - while ( (item = listIter++) != NULL ) - { - if ( item->GetCB() == aFlexTimerServiceCB ) - { - iTimerList.Remove( *item ); - delete item; - return KErrNone; - } - } - return KErrNotFound; - } -// --------------------------------------------------------------------------- -// Loop through timers and find time/timer that must expire next -// Calculate time left to that moment and return it. -// --------------------------------------------------------------------------- -// -TBool CFlexTimerContainer::GetNextTimeout( - TTimeIntervalMicroSeconds& aNextTimeoutDelay ) - { - TSglQueIter listIter( iTimerList ); - TTime currentAbsoluteTime( 0 ); - CFlexTimerItem* item = NULL; - TTime tempTime( 0 ); - TTime nextTimeout( 0 ); - - GetCurrentTime( currentAbsoluteTime ); - // Take first item as a reference value. - listIter.SetToFirst(); - item = listIter++; - if ( item ) - { - item->GetMaxAbsoluteTime( nextTimeout ); - } - - // Find the timer that needs to expire next, and set nextTimeout to the - // time, when the timer needs to expire. - while ( (item = listIter++) != NULL ) - { - item->GetMaxAbsoluteTime( tempTime ); - if ( tempTime < nextTimeout ) - { - nextTimeout = tempTime; - } - } - // Calculate difference between now -> min timeout time. If in past, - // return zero interval - aNextTimeoutDelay = nextTimeout.MicroSecondsFrom( currentAbsoluteTime ); - if ( aNextTimeoutDelay < TTimeIntervalMicroSeconds( 0 ) ) - { - aNextTimeoutDelay = 0; - } - - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_GETNEXTTIMEOUT, - "CFlexTimerContainer::GetNextTimeout;this=%x;aNextTimeoutDelay=%Ld", - ( TUint )this, - aNextTimeoutDelay.Int64() ); - - return !iTimerList.IsEmpty(); - } -// --------------------------------------------------------------------------- -// Excecute selected algorithms and finally fire all timers in candidate list. -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::FireTimers( TFlexTimerAlgorithm aAlgorithmToBeUsed ) - { - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_FIRETIMERS, - "CFlexTimerContainer::FireTimers;this=%x;aAlgorithmToBeUsed=%x", - ( TUint )this, - ( TUint )aAlgorithmToBeUsed ); - - TSglQue candidateList( _FOFF( CFlexTimerItem, iLink ) ); - - TTime currentAbsoluteTime( 0 ); - - GetCurrentTime( currentAbsoluteTime ); - - // Simple algorithm is always executed - SimpleAlgorithm( candidateList, currentAbsoluteTime ); - - if ( EFlexTimerAlgorithmLatestPossible == aAlgorithmToBeUsed ) - { - LatestPossibleAlgorithm( candidateList ); - } - ExpireTimers( candidateList ); - } - -// -// --------------------------------------------------------------------------- -// Loop through timer list, call abort to timer if it is abortable. -// Then remove timer from list and delete it. -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::AbortTimersDueToTimeChange( TInt aReason ) - { - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_ABORTTIMERSDUETOTIMECHANGE, - "CFlexTimerContainer::AbortTimersDueToTimeChange;this=%x;aReason=%d", - ( TUint )this, - aReason ); - - TSglQueIter listIter( iTimerList ); - CFlexTimerItem* item = NULL; - listIter.SetToFirst(); - - // Go through all timers and check if the timer has - // AbortAtSystemTimeChange flag set, if so, abort the timer. - while ( (item = listIter++) != NULL ) - { - if ( item->IsAbortedAtSystemTimeChange() ) - { - item->GetCB()->Abort( aReason ); - iTimerList.Remove( *item ); - delete item; - } - } - } -// --------------------------------------------------------------------------- -// Constructor for CFlexTimerContainer -// --------------------------------------------------------------------------- -// -CFlexTimerContainer::CFlexTimerContainer() : - iTimerList( _FOFF( CFlexTimerItem, iLink ) ), - iLastTicks( 0 ), - iCurrentAbsoluteTime( 0 ) - { - OstTrace1( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_CFLEXTIMERCONTAINER, - "CFlexTimerContainer::CFlexTimerContainer;this=%x", - ( TUint )this ); - TInt err; - - // Get system tick length for converting tics to microseconds. - err = HAL::Get( HAL::ESystemTickPeriod, iTickPeriod ); - - __ASSERT_ALWAYS( - err == KErrNone, - User::Panic( - KFlexTimerContainerPanicCat, - static_cast ( EFlexTimerContainerNoTickPeriod ) ) ); - } -// --------------------------------------------------------------------------- -// Loops through timer list and moves all timers that can be fired to -// candidate list. Can be fired means that minimum time is reached. Note that -// if we are late for some reason (very likely if someone has win size zero), -// candidate list can now contain timers that are late (max time passed). -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::SimpleAlgorithm( - TSglQue& aCandidateList, - TTime& aCurrentTime ) - { - OstTraceExt3( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_SIMPLEALGORITHM, - "CFlexTimerContainer::SimpleAlgorithm;" - "this=%x;aCandidateList=%x;aCurrentTime=%Ld;", - ( TUint )this, - ( TUint )&aCandidateList, - aCurrentTime.Int64() ); - - TSglQueIter listIter( iTimerList ); - CFlexTimerItem* item = NULL; - TTime minTime( 0 ); - - listIter.SetToFirst(); - // Iter++ makes iterator to point to next element if one exists. - // Otherwise NULL. - while ( (item = listIter++) != NULL ) - { - item->GetMinAbsoluteTime( minTime ); - if ( minTime <= aCurrentTime ) - { - OstTraceExt2( TRACE_INTERNAL, - DUP1_CFLEXTIMERCONTAINER_SIMPLEALGORITHM, - "CFlexTimerContainer::SimpleAlgorithm - Adding item;" - "this=%x;item=%x", - ( TUint )this, - ( TUint )item ); - // Remove from candidate list needs to be done before the - // item is added to back to iTimerList, because the lists - // use the same iLink member. - iTimerList.Remove( *item ); - - // This timer can be timeouted, add it to timeout candidate list. - // The list is called candidate list, because the content of the - // list may be pruned by passing it to other algorithms for furher - // prosessing. - aCandidateList.AddLast( *item ); - } - } - } - -// -// --------------------------------------------------------------------------- -// Loops through dropped list and candidate list and find timers where: -// dropped timers right side of the window is earlier than candidate timers -// right side of the window i.e. Candidate can be fired later with dropped -// timer, without additional timer firings -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::LatestPossibleAlgorithm( - TSglQue& aCandidateList ) - { - TSglQueIter listIter( iTimerList ); - TSglQueIter candidateListIter( aCandidateList ); - CFlexTimerItem* droppedItem = NULL; - CFlexTimerItem* candidateItem = NULL; - TTime droppedMaxTime( 0 ); - TTime candidateMaxTime( 0 ); - - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_LATESTPOSSIBLEALGORITHM, - "CFlexTimerContainer::LatestPossibleAlgorithm;" - "this=%x;aCandidateList=%x", - ( TUint )this, - ( TUint )&aCandidateList ); - - listIter.SetToFirst(); - candidateListIter.SetToFirst(); - - droppedItem = listIter++; - - if ( droppedItem != NULL ) - { - // Initiliaze next dropped timeout time to some value. - droppedItem->GetMaxAbsoluteTime( droppedMaxTime ); - - // Loop through dropped timers and find the dropped timer that will have - // shortest time to its timeout. - while ( (droppedItem = listIter++) != NULL ) - { - droppedItem->GetMaxAbsoluteTime( candidateMaxTime ); - if ( droppedMaxTime > candidateMaxTime ) - { - droppedMaxTime = candidateMaxTime; - } - } - - // Loop through candidate timers - while ( (candidateItem = candidateListIter++) != NULL ) - { - candidateItem->GetMaxAbsoluteTime( candidateMaxTime ); - // If candidate can be fired together with dropped timer -> - // don't fire candidate yet. - if ( droppedMaxTime <= candidateMaxTime ) - { - OstTraceExt2( TRACE_INTERNAL, - DUP1_CFLEXTIMERCONTAINER_LATESTPOSSIBLEALGORITHM, - "CFlexTimerContainer::LatestPossibleAlgorithm -" - " Removing item;this=%x;candidateItem=%x", - ( TUint )this, - ( TUint )candidateItem ); - - // Remove from candidate list needs to be done before the - // item is added to back to iTimerList, because the lists - // use the same iLink member. - aCandidateList.Remove( *candidateItem ); - // Add to first so we don't handle this again. - iTimerList.AddFirst( *candidateItem ); - } - } - } - } -// --------------------------------------------------------------------------- -// Loops through candidate list and calls timeout to all timers. -// Then removes timer from list and deletes it. -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::ExpireTimers( - TSglQue& aCandidateList ) - { - OstTraceExt2( TRACE_INTERNAL, - CFLEXTIMERCONTAINER_EXPIRETIMERS, - "CFlexTimerContainer::ExpireTimers;this=%x;candidateList=%x", - ( TUint )this, - ( TUint )&aCandidateList ); - - TSglQueIter candidateListIter( aCandidateList ); - CFlexTimerItem* item = NULL; - - candidateListIter.SetToFirst(); - // Iter++ makes iterator to point to next element if one exists. - // Otherwise NULL. - while ( (item = candidateListIter++) != NULL ) - { - item->GetCB()->Timeout(); - aCandidateList.Remove( *item ); - delete item; - } - } -// --------------------------------------------------------------------------- -// Get current time return current time in FlexTimer engine time base. This -// time base is begins from the first call to GetCurrentTime and it is base on -// system ticks. -// --------------------------------------------------------------------------- -// -void CFlexTimerContainer::GetCurrentTime( TTime& aAbsoluteTime ) - { - TUint32 currentTicks = User::TickCount(); - - // Accumulate current absolute time with the time passed since last - // update. Both currentTicks and iLastTicks are unsigned int types, thus - // "currentTicks - iLastTicks" will handle also the case currentTicks - // overflows. - iCurrentAbsoluteTime += TicksToAbsoluteTime( currentTicks - - iLastTicks ); - - iLastTicks = currentTicks; - - // N.B. Even though the time is is returned as TTime, this time has own - // time base. (See function description) - aAbsoluteTime = iCurrentAbsoluteTime; - } - - - - - -