summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2017-01-25 11:22:56 +0100
committerJan-Marek Glogowski <glogow@fbihome.de>2017-07-13 12:10:22 +0200
commitd93acb77667ecdb78b53a1be626ca2e000813828 (patch)
tree43724212eaccd33c68dd78cea46ab8a2b9b17dda
parentd348035a60361a1b9ba9eb7b67013204a24a6633 (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.hxx2
-rw-r--r--vcl/inc/svdata.hxx4
-rw-r--r--vcl/source/app/scheduler.cxx37
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()