diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2017-01-25 11:22:56 +0100 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2017-07-13 12:10:22 +0200 |
commit | d93acb77667ecdb78b53a1be626ca2e000813828 (patch) | |
tree | 43724212eaccd33c68dd78cea46ab8a2b9b17dda | |
parent | d348035a60361a1b9ba9eb7b67013204a24a6633 (diff) |
Correctly account starting tasks
When (re-)starting the system timer for new task, we have to take
the already passed time into account to correctly set the new
timeout time for the system timer.
Change-Id: I1c1c61b3e54bd14d9451c53150251534b2a960f0
-rw-r--r-- | include/vcl/scheduler.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 4 | ||||
-rw-r--r-- | vcl/source/app/scheduler.cxx | 37 |
3 files changed, 24 insertions, 19 deletions
diff --git a/include/vcl/scheduler.hxx b/include/vcl/scheduler.hxx index 1dd127c96f9a..f5edb214349a 100644 --- a/include/vcl/scheduler.hxx +++ b/include/vcl/scheduler.hxx @@ -38,7 +38,7 @@ class VCL_DLLPUBLIC Scheduler final static inline void UpdateMinPeriod( ImplSchedulerData *pSchedulerData, sal_uInt64 nTime, sal_uInt64 &nMinPeriod ); - static void ImplStartTimer ( sal_uInt64 nMS, bool bForce = false ); + static void ImplStartTimer ( sal_uInt64 nMS, bool bForce, sal_uInt64 nTime ); public: static constexpr sal_uInt64 ImmediateTimeoutMs = 1; diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index f9de696650ad..dcbbc00ea9bc 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -324,8 +324,8 @@ struct ImplSchedulerContext ImplSchedulerData* mpFirstSchedulerData = nullptr; ///< list of all active tasks ImplSchedulerData* mpLastSchedulerData = nullptr; ///< last item of the mpFirstSchedulerData list SalTimer* mpSalTimer = nullptr; ///< interface to sal event loop / system timer - sal_uInt64 mnTimerPeriod = 0; ///< current timer period - sal_uInt64 mnLastProcessTime = 0; ///< last time a task was processed + sal_uInt64 mnTimerStart = 0; ///< start time of the timer + sal_uInt64 mnTimerPeriod = SAL_MAX_UINT64; ///< current timer period bool mbNeedsReschedule = false; ///< we need to reschedule }; diff --git a/vcl/source/app/scheduler.cxx b/vcl/source/app/scheduler.cxx index 8c04d5916688..8e166a974ac2 100644 --- a/vcl/source/app/scheduler.cxx +++ b/vcl/source/app/scheduler.cxx @@ -108,7 +108,7 @@ void Scheduler::ImplDeInitScheduler() rSchedCtx.mpFirstSchedulerData = nullptr; rSchedCtx.mpLastSchedulerData = nullptr; - rSchedCtx.mnTimerPeriod = 0; + rSchedCtx.mnTimerPeriod = InfiniteTimeoutMs; } /** @@ -118,7 +118,7 @@ void Scheduler::ImplDeInitScheduler() * waiting for, do nothing - unless bForce - which means * to reset the minimum period; used by the scheduled itself. */ -void Scheduler::ImplStartTimer(sal_uInt64 nMS, bool bForce) +void Scheduler::ImplStartTimer(sal_uInt64 nMS, bool bForce, sal_uInt64 nTime) { ImplSVData* pSVData = ImplGetSVData(); if (pSVData->mbDeInit) @@ -133,17 +133,27 @@ void Scheduler::ImplStartTimer(sal_uInt64 nMS, bool bForce) ImplSchedulerContext &rSchedCtx = pSVData->maSchedCtx; if (!rSchedCtx.mpSalTimer) { + rSchedCtx.mnTimerStart = 0; rSchedCtx.mnTimerPeriod = InfiniteTimeoutMs; rSchedCtx.mpSalTimer = pSVData->mpDefInst->CreateSalTimer(); rSchedCtx.mpSalTimer->SetCallback(Scheduler::CallbackTaskScheduling); } - if ( !nMS ) - nMS = 1; + if ( nMS > InfiniteTimeoutMs ) + nMS = InfiniteTimeoutMs; + if ( nMS < ImmediateTimeoutMs ) + nMS = ImmediateTimeoutMs; + assert(SAL_MAX_UINT64 - nMS >= nTime); + + sal_uInt64 nProposedTimeout = nTime + nMS; + sal_uInt64 nCurTimeout = ( rSchedCtx.mnTimerPeriod == InfiniteTimeoutMs ) + ? SAL_MAX_UINT64 : rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod; // Only if smaller timeout, to avoid skipping. - if (bForce || nMS < rSchedCtx.mnTimerPeriod) + if (bForce || nProposedTimeout < nCurTimeout) { + SAL_INFO( "vcl.schedule", " Starting scheduler system timer (" << nMS << "ms)" ); + rSchedCtx.mnTimerStart = nTime; rSchedCtx.mnTimerPeriod = nMS; rSchedCtx.mpSalTimer->Start( nMS ); } @@ -171,7 +181,7 @@ inline bool Scheduler::HasPendingTasks( const ImplSchedulerContext &rSchedCtx, const sal_uInt64 nTime ) { return ( rSchedCtx.mbNeedsReschedule || ((rSchedCtx.mnTimerPeriod != InfiniteTimeoutMs) - && (nTime >= rSchedCtx.mnLastProcessTime + rSchedCtx.mnTimerPeriod )) ); + && (nTime >= rSchedCtx.mnTimerStart + rSchedCtx.mnTimerPeriod )) ); } bool Scheduler::HasPendingTasks() @@ -201,7 +211,6 @@ bool Scheduler::ProcessTaskScheduling() if ( pSVData->mbDeInit || !HasPendingTasks( rSchedCtx, nTime ) ) return false; rSchedCtx.mbNeedsReschedule = false; - rSchedCtx.mnLastProcessTime = nTime; ImplSchedulerData* pSchedulerData = nullptr; ImplSchedulerData* pPrevSchedulerData = nullptr; @@ -264,23 +273,19 @@ next_entry: } // delete clock if no more timers available, - if ( !pSVData->maSchedCtx.mpFirstSchedulerData ) + if ( InfiniteTimeoutMs == nMinPeriod ) { if ( pSVData->maSchedCtx.mpSalTimer ) pSVData->maSchedCtx.mpSalTimer->Stop(); - if ( ImmediateTimeoutMs == nMinPeriod ) - SAL_INFO("vcl.schedule", "Unusual - no more tasks available - stop timer"); - else - SAL_INFO("vcl.schedule", "Idles available - handle immediate"); + SAL_INFO("vcl.schedule", " Stopping system timer"); + pSVData->maSchedCtx.mnTimerPeriod = nMinPeriod; } else { - Scheduler::ImplStartTimer( nMinPeriod, true ); + Scheduler::ImplStartTimer( nMinPeriod, true, nTime ); SAL_INFO("vcl.schedule", "Calculated minimum timeout as " << nMinPeriod ); } - pSVData->maSchedCtx.mnTimerPeriod = nMinPeriod; - if ( pMostUrgent ) { SAL_INFO( "vcl.schedule", tools::Time::GetSystemTicks() << " " @@ -307,7 +312,7 @@ next_entry: void Task::StartTimer( sal_uInt64 nMS ) { - Scheduler::ImplStartTimer( nMS, false ); + Scheduler::ImplStartTimer( nMS, false, tools::Time::GetSystemTicks() ); } void Task::SetDeletionFlags() |