Recent

Author Topic: Random freeze with fpTimer  (Read 21477 times)

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #30 on: March 05, 2015, 06:45:10 pm »
You are right, but if i have the right knowledge on how to buid a timer, i didn't came here asking for help with TfpTimer :)

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #31 on: March 05, 2015, 07:23:10 pm »
Anyway, i'm having a problem and i don't know what cause it.

I'm using three timers, one for the main application, one for a process monitoring class, and the last one for another class.

The three timers seems to conflict each other sometimes, and this lead one of the timer to fire at least once after i call his stop procedure.  This is causing me a lot of troubles.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Random freeze with fpTimer
« Reply #32 on: March 06, 2015, 10:01:00 am »
The three timers seems to conflict each other sometimes
This is not a fix but only a suggestion on how to improve your current situation. Using multiple timers which interlap each other constantly is not a good idea. For example, having timer1 fire every 1000ms, timer2 every 2000ms and timer3 every 3000ms means that around every 6000ms you have all 3 timers fighting for attention, every 2 seconds 2 timers are fighting for attention, and every 3 seconds the other 2 timers are fighting, and that happens constantly over time. You might improve this by forcing fired timer to wait for others to finish first, but unless your implementation is carefully planned there is a lock risk. I am more for you to first try another thing. Instead of using such round numbers like 1000, 2000 and 3000 (or whatever you have), you can use prime numbers. There are prime number lists on the net like this one http://primes.utm.edu/lists/small/10000.txt, so you don't have to calculate them on your own. In example case I would for example replace 1000 with 977, 2000 with 2011, and 3000 with 3049. This leads to much more desirable timer conflict distribution over time, so now you have a very rare situation when all 3 timers fight for attention, which is usually a big improvement. That makes your application more responsive to the user. You don't have to worry about non-roundness of prime number timer periods since OS can not fire exactly at 1000ms anyway. Usually error on windows is up to 10ms, and normal timers faster than that are not usable anyway. There are more precise special timers and time measurement techniques but that is another story. After all, if you are looking for smooth user GUI experience as an imperative, timers code should not belong to the same thread as your application. But, that is yet another story...
« Last Edit: March 06, 2015, 10:13:50 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #33 on: March 06, 2015, 03:18:43 pm »
Thank you for your tip Avra, but actually i don't have any problems with response of the GUI, this because it's a non-gui application :)

I'm coding a keyboard-mouse emulator for xinput controllers, and i need three timers to made the whole thing run.

One timer is inside che class that scan the running process, identify if is from a know game and load the XML with the joypad configuration. It fires every second.

The second timer is the pad emulation class, it check the xinput dell and press the keys. It fires every 1 millisecond.

The third is inside the main program, fires ever second and check if a game is running (from the first class) and start/stop the emulation (from the second class).

There isn't a GUI and the whole application didn't use much CPU, so i don't have problems with performance, until i don't use the basic TTimer.
This because TTimer didn't halt the application execution, so i had to disable and reanable it inside the ontimer event, leading to a performance loss because basically is destroing/recreating each time.

fpTimer works well, but is bugged and freeze randomly. The fix provided by EngKin works, but freeze randomy when i have more timers, so i can't use it. The timerthread by GetMen works, but cause a lot of problems when there are more timers, even worse than fptimer.

Actually i'm using two Ttimer for the 1-second events and the fixed fpTimer for the 1-millisecond event, and everything seems to work well.

But i'm curious to know why both fptimer and timerthread seems to conflict each other, freezing and firing when disabled.
« Last Edit: March 06, 2015, 03:23:13 pm by Tharon »

balazsszekely

  • Guest
Re: Random freeze with fpTimer
« Reply #34 on: March 06, 2015, 04:44:28 pm »
Quote
It fires every 1 millisecond.

I used the GetTickCount64 function because it's available on every platform, and doesn't have the 49.7 days limit. With GetTickCount/GetTickCount64 you cannot measure time smaller then 15 ms. fpTimer uses an alternative _GetTickCount, with the "now" function inside, which is even worse, so you can forget about 1ms.
Since you're on windows, you should import the timeGetTime function, combined with timeBeginPeriod and timeEndPeriod  you can get close to 1 ms, at least less then 5ms. I'm not surprised your code it's not working, you didn't mention the necessity of high precision.
« Last Edit: March 06, 2015, 04:49:26 pm by GetMem »

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #35 on: March 06, 2015, 08:20:52 pm »
I don't really need high precision, i use 1 ms but 15/20ms is just fine. So precision isn't the problem, but the conflicting of more timers.

balazsszekely

  • Guest
Re: Random freeze with fpTimer
« Reply #36 on: March 06, 2015, 08:36:44 pm »
Now I' m  100% convinced that your code is the main problem, not the timer. Please post a small project when you can reproduce the timers conflict.
By the way,  you don't need 3 timers, one timer is more than enough. If the interval is 20 ms, after 50 tick you got one second. Run 1 timer, then call specific function from class A  and class B, or you can  pass the timer(as parameter in the constructor) to each class, it all depends on your program design. Remember that even 20ms is a joke with fptimer "now" function, you don't have to believe me, just run a few test.
« Last Edit: March 07, 2015, 06:14:20 am by GetMem »

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #37 on: March 07, 2015, 12:53:50 pm »
I did a lot of tests, and my code is fine and working now, with only one tfptimer and two ttimer.  And yes, i need those three timers because i need to start and stop them individually. Using only one and passing it will made the whole code a lot more complex.
« Last Edit: March 07, 2015, 01:15:25 pm by Tharon »

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: Random freeze with fpTimer
« Reply #38 on: March 09, 2015, 11:22:05 am »
Actually i'm using two Ttimer for the 1-second events and the fixed fpTimer for the 1-millisecond event, and everything seems to work well.

But i'm curious to know why both fptimer and timerthread seems to conflict each other, freezing and firing when disabled.
As I have already said, anything less then 10ms is not realistic with out of the box timers. You can see it your self if you log and show how many times per second is your 1ms timer executed. I guess it will fire a little less then about 100 times per second.

Three things come to my mind what you can do, and some have already been mentioned.
1) Use non standard timers. I can not remember if there exist Windows multimedia 1ms timer for FPC/LAZ, but there is a cross platform FPC/LAZ EpikTimer which can also fire at 1ms intervals without problems. You can find it here: http://wiki.lazarus.freepascal.org/EpikTimer
2) Disable specific timer on entering it, and reenable it before leaving it. This will prevent multiple firing when there is some OS congestion, and maybe even solve your freezing problem.
3) Use single 1ms EpikTimer for firing code that you currently hold in 3 timers. Just make some global counter and inside of fired timer have something like this:
Code: [Select]
Inc(Counter);
if (Counter mod 1000)=0 then
   Exec1secTimer1Code()
elsif ((Counter + 500) mod 1000)=0 then
   Exec1secTimer2Code()
else
  Exec1msecTimerCode();
It's that simple. This way you can even try to stay with standard 10ms timer, but all numbers would then need to be divided with 10.
« Last Edit: March 09, 2015, 11:24:38 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Tharon

  • Jr. Member
  • **
  • Posts: 61
Re: Random freeze with fpTimer
« Reply #39 on: March 09, 2015, 03:33:25 pm »
As i said before, i don't really need a 1ms precision, anything between 20 and 50 ms is enough. I've choose to set it to 1ms only to stress the timers and check their reliability. Since they are conflicting at 1ms, i can exept conflict even at 15ms or more, just more rarer.

With the two ttimers and one instance of the fixed fptimer i didn't had any problem with all the test i did.
I will stick with this solution until i had the spare time to rework the code (it's a 3000 lines of code, and growing) to have only one timer. Actually, i was only curious to know why the two instance of timers are conflicting.

 

TinyPortal © 2005-2018