mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
Timer: smaller glitches with 'sleep time remainder', TimerTest: proper close / wait for Timer enabled applications example
git-svn-id: svn://ultimatepp.org/upp/trunk@2549 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
335799d2c9
commit
cd8510db6e
6 changed files with 58 additions and 13 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
Timer::Timer()
|
||||
{
|
||||
granularity = 2;
|
||||
granularity = 10;
|
||||
run = true;
|
||||
t.Run(THISBACK(TimerThread));
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ void Timer::KillTimeCallback(void *id) {
|
|||
KillTimeCallbacks(id);
|
||||
}
|
||||
|
||||
void Timer::TimerProc(dword time)
|
||||
void Timer::TimerProc(dword time, int & leftsleep)
|
||||
{
|
||||
if(IsPanicMode())
|
||||
return;
|
||||
|
|
@ -87,7 +87,7 @@ void Timer::TimerProc(dword time)
|
|||
// sTimerLock.Leave();
|
||||
// //***
|
||||
// sTimerLock.Enter();
|
||||
while(list->GetNext() != list && list->GetNext()->time < time) {
|
||||
while(list->GetNext() != list && ((leftsleep = (list->GetNext()->time - time)) <= 0)) {
|
||||
TimeEvent *e = list->GetNext();
|
||||
e->Unlink();
|
||||
if(e->delay < 0)
|
||||
|
|
@ -98,6 +98,7 @@ void Timer::TimerProc(dword time)
|
|||
delete e;
|
||||
}
|
||||
sTimerLock.Leave();
|
||||
if(leftsleep < 0) leftsleep = granularity; //if last done has been processed and no more in queue, ensure good sleep
|
||||
}
|
||||
|
||||
//SAME API AS IN Ctrl
|
||||
|
|
@ -145,9 +146,11 @@ void Timer::SetTimerGranularity(int ms)
|
|||
|
||||
void Timer::TimerThread()
|
||||
{
|
||||
int leftsleep;
|
||||
while(run)
|
||||
{
|
||||
TimerProc(GetTickCount());
|
||||
Sleep(granularity); //granularity
|
||||
leftsleep = granularity;
|
||||
TimerProc(GetTickCount(), leftsleep);
|
||||
Sleep(min(granularity, leftsleep));
|
||||
}
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ private:
|
|||
void KillTimeCallbacks(void *id, void *idlim);
|
||||
bool ExistsTimeCallback(void *id);
|
||||
void KillTimeCallback(void *id);
|
||||
void TimerProc(dword time);
|
||||
void TimerProc(dword time, int & leftsleep);
|
||||
|
||||
void KillTimeCallbacks(void *id);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@ things wont get to execution, until a current task is finished,
|
|||
and the timer queue can check whether time has come for the next
|
||||
task.]&]
|
||||
[s0;2 &]
|
||||
[s0;i150;O0; [2 Because of it, the timing is not as accurate as maybe
|
||||
desired and can have `"timer glitches/jitter`", depending on
|
||||
work load..]&]
|
||||
[s0;i150;O0; [2 Thus, the timing is not as accurate as maybe desired
|
||||
and can have `"timer glitches/jitter`", depending on work load..]&]
|
||||
[s0;2 &]
|
||||
[s0;i150;O0; [2 Favorite use is to schedule some `*non`*`-timing`-critical
|
||||
work for `"somewhere`-around`-in`-the`-future`".]&]
|
||||
work for `"somewhere`-around`-in`-the`-future`", like i.e. observe
|
||||
some not too strict timing constraints in custom communication
|
||||
protocols (answer needs to come in within X time, keep alive
|
||||
messages..)]&]
|
||||
[s0;2 &]
|
||||
[s0;i150;O0; [2 For timing critical stuff, consider using OS native
|
||||
timer means, for WIN32 SetTimer (in windowing environment, using
|
||||
|
|
|
|||
|
|
@ -14,11 +14,16 @@ class TimerTest : public WithLayout<TopWindow> {
|
|||
public:
|
||||
typedef TimerTest CLASSNAME;
|
||||
TimerTest();
|
||||
~TimerTest();
|
||||
|
||||
void Close0();
|
||||
virtual void Close();
|
||||
|
||||
void Info(const String & s);
|
||||
void Test();
|
||||
private:
|
||||
Timer t;
|
||||
Atomic demo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
description "Test for Timer package\377";
|
||||
|
||||
uses
|
||||
CtrlLib,
|
||||
Timer;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,17 @@
|
|||
#define REPEAT_TEST
|
||||
|
||||
TimerTest::TimerTest()
|
||||
: demo(0)
|
||||
{
|
||||
CtrlLayout(*this, "Window title");
|
||||
|
||||
int a = AtomicInc(demo);
|
||||
ASSERT(a==1); //preload, 1 means running demo mode, 2 means a cb is executing
|
||||
|
||||
#ifdef REPEAT_TEST
|
||||
t.SetTimeCallback(-1000, THISBACK(Test), 0);
|
||||
t.SetTimeCallback(-100, THISBACK(Test), (int)this);
|
||||
#else
|
||||
PostCallback(THISBACK(Test));
|
||||
t.SetTimeCallback(0, THISBACK(Test), (int)this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -20,13 +25,41 @@ void TimerTest::Info(const String & s)
|
|||
|
||||
void TimerTest::Test()
|
||||
{
|
||||
int a = AtomicInc(demo);
|
||||
ASSERT(a==2);
|
||||
|
||||
Info("O");
|
||||
RLOG("O");
|
||||
|
||||
a = AtomicDec(demo);
|
||||
if(a<=0)
|
||||
return;
|
||||
ASSERT(a>=0);
|
||||
|
||||
#ifdef REPEAT_TEST
|
||||
#else
|
||||
t.SetTimeCallback(1000, THISBACK(Test), 0);
|
||||
t.SetTimeCallback(100, THISBACK(Test), (int)this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TimerTest::Close()
|
||||
{
|
||||
t.KillTimeCallback((int)this);
|
||||
int a = AtomicDec(demo);
|
||||
Thread::Start(THISBACK(Close0));
|
||||
}
|
||||
|
||||
void TimerTest::Close0()
|
||||
{
|
||||
while(AtomicRead(demo) > 0) Sleep(1);
|
||||
ASSERT(AtomicRead(demo)==0);
|
||||
TopWindow::Close();
|
||||
}
|
||||
|
||||
TimerTest::~TimerTest()
|
||||
{
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
TimerTest().Run();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue