|
|
On 7/9/21 7:25 PM Ian MacArthur wrote:
On 9 Jul 2021, at 17:54, Bill Spitzak wrote:
I vaguely remember that repeat_timeout, if the calculated remaining time was zero or negative, would punt and instead act like add_timeout. My feeling was that if a program was too slow it would be running the timeouts continuously if the alternative of just calling it immediately was done. There was certainly no testing as to whether this was the correct solution or not.
The current solution is clearly to deliver the next timeout as soon
as possible:
time += missed_timeout_by; if (time < -.05) time = 0;
After this statement the timeout is queued with delta == time (0).
However, my tests seem to indicate that something's going awry with
the calculation of missed_timeout_by . There are some strange effects
which I'm still investigating.
But, to me at least, it sounds like it probably is.
In don't know yet what exactly is happening with the current code.
But I imagine that a user program that's not able to process the
timeouts fast enough would be entering a loop, similar to an idle
callback. Skipping single repeat_timeout's would lead to
undeterministic behavior.
And it does (in parts), see my test program logs below.
The crux, like Bill said, is that is you are running so slowly that you miss the timeout, then trying to “fill in” all the missing timeouts is only going to make matters worse, I imagine...
Sure, as I said above, that's what I'd expect. This is a program
error but wouldn't it be easier to diagnose the error if FLTK would
not "try to help" and skip particular timer callbacks?
I'm attaching a test program as announced: timer2.cxx.
The following constants describe the test case:
const double delay = 0.500; // timer delay const int timeouts = 8; // number of timeouts to be tested const int load1 = 600; // simulated workload in ms before Fl::repeat_timeout()
Fl::repeat_timeout(delay) is called in a timer callback after a
simulated workload of 600 ms duration which is clearly longer than
the timer delay. The test is repeated 8 times. The outcome is
"interesting": deterministic but different on all three major
platforms. Note that I tested Windows in cross-compiler mode on my
Linux box, but this does hopefully not matter.
(1) Linux:
$ bin/test/timer2
Tick -2 at 50.5994
Tick -1 at 51.1001
Tick 0 at 51.6000, delay = 0.5000
Tick 1 at 52.7004, delta = 1.1004, total = 1.1004, average =
1.100448
Tick 2 at 53.3009, delta = 0.6004, total = 1.7009, average =
0.850435
Tick 3 at 54.4017, delta = 1.1009, total = 2.8017, average =
0.933907
Tick 4 at 55.0020, delta = 0.6003, total = 3.4020, average =
0.850496
Tick 5 at 56.1030, delta = 1.1010, total = 4.5030, average =
0.900599
Tick 6 at 56.7033, delta = 0.6003, total = 5.1033, average =
0.850555
Tick 7 at 57.8042, delta = 1.1009, total = 6.2042, average =
0.886321
Tick 8 at 58.4046, delta = 0.6003, total = 6.8046, average =
0.850572
Done.
(2) Windows:
$ wine bin/test/timer2.exe
Tick -2 at 4.7490
Tick -1 at 5.2510
Tick 0 at 5.7520, delay = 0.5000
Tick 1 at 6.8550, delta = 1.1030, total = 1.1030, average =
1.103000
Tick 2 at 7.9570, delta = 1.1020, total = 2.2050, average =
1.102500
Tick 3 at 9.0600, delta = 1.1030, total = 3.3080, average =
1.102667
Tick 4 at 10.1630, delta = 1.1030, total = 4.4110, average =
1.102750
Tick 5 at 11.2660, delta = 1.1030, total = 5.5140, average =
1.102800
Tick 6 at 12.3700, delta = 1.1040, total = 6.6180, average =
1.103000
Tick 7 at 13.4730, delta = 1.1030, total = 7.7210, average =
1.103000
Tick 8 at 14.5760, delta = 1.1030, total = 8.8240, average =
1.103000
Done.
(3) macOS:
$ bin/test/timer2
Tick -2 at 0.4407
Tick -1 at 0.9397
Tick 0 at 1.4412, delay = 0.5000
Tick 1 at 2.4445, delta = 1.0032, total = 1.0032, average =
1.003243
Tick 2 at 3.4420, delta = 0.9975, total = 2.0008, average =
1.000387
Tick 3 at 4.4445, delta = 1.0025, total = 3.0033, average =
1.001087
Tick 4 at 5.4402, delta = 0.9957, total = 3.9990, average =
0.999742
Tick 5 at 6.4444, delta = 1.0042, total = 5.0032, average =
1.000643
Tick 6 at 7.4398, delta = 0.9953, total = 5.9986, average =
0.999760
Tick 7 at 8.4445, delta = 1.0047, total = 7.0032, average =
1.000461
Tick 8 at 9.4445, delta = 1.0000, total = 8.0033, average =
1.000408
Done.
(1) Linux: The effective delay alternates between 1.1 and 0.6
seconds (reproducibly). This is certainly not as designed and very
likely a bug in the calculation and handling ((not) resetting?) of missed_timeout_by. I'm investigating...
The average is closest to the intended delay: ~0.85 sec.
(2) Windows: there's reproducibly no correction, the effective delay
is always ~1.1 + x seconds, hence the average is also ~1.1 sec.
(3) macOS: the effective delay is ~1.0 seconds, as Manolo described:
2 * 0,5 = 1.0 sec. Average 1.0 is the intended delay times two.
That is: three platforms -- three different implementations -- three
different results.
Sure, these are border cases, but I see that Wayland and Android are
other candidates for having their own implementations. This should
be avoided!
What we IMHO need to do is:
(a) define and describe and eventually document the "correct
behavior"
(b) unify all platforms by providing a platform-agnostic common
algorithm
The discussion here is good to solve (a) and I'm striving to do (b)
which should use an algorithm defined by (a) and can be modified in
one place for all current and future platforms.
Please feel free to use my test program with other cases and report
your findings. The constants at the top of the program may be
modified as you need. A better test program would have a GUI to
modify the test params, but I don't know whether I'll ever do that.
And there will likely be completely different test scenarios...
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/b82068ec-a035-40ef-d5f1-ae2774d88c9a%40online.de.
[ Direct Link to Message ] | |
|
| |