From: Martin Z. <co...@mz...> - 2010-02-01 17:57:01
Attachments:
synchronise.conf
synchronise.patch.tar.gz
|
Hi! I had a long train ride today and, after staring at the beautiful, snow-filled landscape for hours, had a go at synchronising widget updates. I won't commit this to SVN before I have the all-go, though, as I don't know whether my patch might introduce a lag on some LCD updates and whether you actually want synchronised widgets. That being said, the patch works flawless on the X display driver and my picoLCD 256x64. Here's what I did: I basically duplicated "timer.c" and "timer.h". I also changed all the widgets to call "timer_add_widget()" instead of "timer_add()". This function stores all the necessary callback data and allocates a new timer -- but only one timer for each update interval. This timer then regularly calls "timer_process_group()", which processes all widgets with the given update data. This not only synchronises widgets, but also gets rid of a lot of unessesary timers. Simple, but quite effective. If you wish to, please run "lcd4linux" with the attached configuration file "synchronise.conf". You will see a lot of icons that pop up and vanish rather irregularly. After applying my patch, all boxes of a given update interval appear at once and vanish in the same way. By the way, I added "timer_group.c" and "timer_group.h" to "Makefile.am", ran "./bootstrap", "./configure" and "make". I hope that this was the correct thing to do -- I have never used "automake" before... ;) Best regards, Martin -- www.mzuther.de www.radix-musik.de |
From: Michael R. <mi...@re...> - 2010-02-04 03:01:29
|
Hi Martin, > I had a long train ride today and, after staring at the beautiful, > snow-filled landscape for hours, had a go at synchronising widget > updates. I won't commit this to SVN before I have the all-go, though, > as I don't know whether my patch might introduce a lag on some LCD > updates and whether you actually want synchronised widgets. That being > said, the patch works flawless on the X display driver and my picoLCD > 256x64. > > Here's what I did: I basically duplicated "timer.c" and "timer.h". I > also changed all the widgets to call "timer_add_widget()" instead of > "timer_add()". This function stores all the necessary callback data and > allocates a new timer -- but only one timer for each update interval. > This timer then regularly calls "timer_process_group()", which processes > all widgets with the given update data. This not only synchronises > widgets, but also gets rid of a lot of unessesary timers. Simple, but > quite effective. Sounds very interesting! What do you think is the reason for the various timers loosing sync over time? I did *not* apply the patch, for a simple reason: I don't think its necessary to duplicate a lot of stuff, because if the new syncronous timers are fine, why not just replace the olt timers completely? Is there anybody / anything that relies on the old functionality? bye, Michael -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Martin Z. <co...@mz...> - 2010-02-04 14:10:08
|
Hi Michael, I think you have gotten me wrong. The timers run pretty fine. The problem is that each widget has its own timer with its own starting time, so the widgets aren't synchronised to begin with. Also, I have *not* rewritten the timer code. I have only copied "timer.c" because I wanted to keep the basic functionality of allocating memory for storing callback functions and so on. I did this to save me work and also because I'm not used to programming in C (I'm more used to C++). The *functionality* of "timer_group.c" is completely different from "timer.c": it creates a group and a corresponding timer that registers "the group" as its callback. Widgets are added to the group with their callback data (callback function and data, "one_shot" and so on) and each widget's callback function is called when the group timer "triggers". Let's look at a simple example of three widgets: Widget Line1 { [...] update 200 } Widget Line2 { [...] update 500 } Widget Line3 { [...] update 200 } *** Current behaviour *** When widget "Line1" is initialised, a new timer (200 ms) is set up and stores callback function, callback data and a few status things. This is repeated for "Line2" (500 ms) and "Line3" (200 ms), resulting in three timers. As initialisation takes time, there is a small delay between starting the timers for "Line1" and "Line3", even though they have the same update interval. This delay (to keep it simple, let's say 1 ms for each widget) is responsible for the "drifting". Normally, "Line1" and "Line3" would be updated after each other. But occasionally, "Line2" gets in between: ms widget --------------- 200 Line1 202 Line3 400 Line1 402 Line3 501 Line2 600 Line1 602 Line3 800 Line1 802 Line3 1000 Line1 1001 Line2 <-- 1002 Line3 And this is were my patch comes in. *** Synchronised widget updates *** When widget "Line1" is initialised, a group (200 ms) is created and a corresponding timer is set up. However, callback data are *not* stored by the timer, but by the group. The timer instead stores callback data of *the group*. When widget "Line2" is initialised, a second group (500 ms) is created, a corresponding timer is set up and callback data are stored in this group. Now it gets interesting: when widget "Line3" is initialised, *no* new group is created. Instead, the first group (200 ms) is used to store this widget's callback data. ms widgets --------------- 200 Line1, Line3 400 Line1, Line3 501 Line2 600 Line1, Line3 800 Line1, Line3 1000 Line1, Line3 1001 Line2 <-- So now, you only have two timers instead of three, and widgets with the same update interval are updated at the same time. Nice and easy... :) This functionality can, however, not be included in "timer.c" -- at least not easily. This is because: * many of the display drivers use "timer_add()", but shouldn't be in a group with widgets * scrolling text widgets (i.e. marquee or ping pong) define two timers, and my code breaks if the scrolling timer is added to a group which already contains widgets (this could probably be solved easily) Now that was a long email. :) Hopefully, I have clarified myself... Martin -- www.mzuther.de www.radix-musik.de |
From: Michael R. <mi...@re...> - 2010-02-04 15:16:58
|
Hi Martin, > I think you have gotten me wrong. The timers run pretty fine. The > problem is that each widget has its own timer with its own starting > time, so the widgets aren't synchronised to begin with. Ok, thanks for your explanation, now I got you! BUT (you know, there's alwys a BUT from my side ;-) I know this "timers getting out of sync" problem for years, never had the time to dig into that. While your modification surely solves this for widget updates, I want to get rid of it fundamentally. Apart from that, one (future) extension would be impossible: think of two widgets, both having an update timer of say 500 msec, but the second one is being pre-delayed by 250 msec (there is no such thing like a initial delay at the moment, but you never can tell with the future..) I think a clean solution would be to re-sync the timers. Given the fact that there should be no timer less that 10 msec, and that computers are fast these days, there shouldn't be a difference of mor than 1 or 2 msec. But they sum up with the current code. My idea would be to process not only the timer(s) that expired *now* but also timers that expire at now+5 msec, and set the "last time fired" timestamp for all these timers to *now*. the last point should be already in there: the timer_process() gets the current timestamp only once, at the very beginning. So "slow" callbacks would not affect the timing. Another needed functionality is already inside: the loop not only looks for timers that expire *now*, but also for timers that expired in the past. I can think of several possible solutions: a) when looking for expired timers, look a short period time into the future b) call timer_process() not exactly at the timeout of the next timer, but a bit later, so more timers would have expired. c) do some rounding of timeout values, probably depending on the delay timne (e.g. 10% of delay time) especially c) sounds interesting to me: if a timer has a timeout of 200 msec, round the next start time to 20msec, so it expires at 0:0200, 0:0400, 0:0600, .... I hope you all do understand what I'm talking about.... bye, Michael -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Martin Z. <co...@mz...> - 2010-02-06 21:20:26
|
Dear Michael! > I hope you all do understand what I'm talking about.... To be honest, I don't... :) First, I think we have to define the problem, because in my opinion there are two of them that need separate solving. One is the time-shift that is introduced by processing. The other one is that of unsynchronised widgets, and I have already solved that, at least partially. So let's talk about time-shifts. On looking through the code again, I think I have pinpointed the problem. First, using one-shot timers for widgets doesn't seem to make sense to me. First, there is the overhead of deleting the old one and creating a new one. Second, most (if not all) widgets are triggered regularly, so using one-shot timers isn't the best solution. If this was changed (I have temporally done this for "widget_icon.c" while so far ignoring the problem of timer deletion or widget deletion), we can now move on to "timer.c". First, have a look at line 182, which is where a single *continuous* timer is being respawned: } else { Timers[i].when = now; timer_inc(&Timers[i].when, Timers[i].interval); } I think the second line (which sets the timer to "now") is plain wrong because it automatically delays a timer by the time the callback needs for processing. So this line should be removed as fast as possible! Another, albeit smaller, problem lies in line 206: /* delay until next timer event */ struct timeval diff; timersub(&Timers[min].when, &now, &diff); delay->tv_sec = diff.tv_sec; /* microseconds to nanoseconds!! */ delay->tv_nsec = diff.tv_usec * 1000; Here, the delay to the next timer event is too long, because we ignore the processing time between reading the value for "now" and calculating the delay. What we need here is to update the value for "now" and only then calculate the delay: /* delay until next timer event */ struct timeval diff; timersub(&Timers[min].when, &now, &diff); gettimeofday(&now, NULL); [...] Now for a real time test: one single icon widget with update set to 1000 ms. I have also removed the timers with id 0, as they are used for updating the X11 driver. They do, however, behave just as the other timers. Before the changes mentioned above (continuous timers and the two code sections): Timers[ 1]: 1265490676.166966 Timers[ 2]: 1265490677.167110 Timers[ 1]: 1265490678.167248 Timers[ 2]: 1265490679.167385 Timers[ 1]: 1265490680.167532 Timers[ 2]: 1265490681.167672 Timers[ 1]: 1265490682.167822 Timers[ 2]: 1265490683.167960 Timers[ 1]: 1265490684.168108 Timers[ 2]: 1265490685.168249 Timers[ 1]: 1265490686.168387 Timers[ 2]: 1265490687.168525 Timers[ 1]: 1265490688.168652 Timers[ 2]: 1265490689.168780 Timers[ 1]: 1265490690.168908 After 15 seconds (and therefore 15 updates), we have a time-shift of 1.9 ms. Just for one single widget! After applying the changes: Timers[ 1]: 1265490514.609078 Timers[ 1]: 1265490515.609079 Timers[ 1]: 1265490516.609078 Timers[ 1]: 1265490517.609078 Timers[ 1]: 1265490518.609079 Timers[ 1]: 1265490519.609078 Timers[ 1]: 1265490520.609076 Timers[ 1]: 1265490521.609079 Timers[ 1]: 1265490522.609078 Timers[ 1]: 1265490523.609079 Timers[ 1]: 1265490524.609079 Timers[ 1]: 1265490525.609079 Timers[ 1]: 1265490526.609078 Timers[ 1]: 1265490527.609094 <-- glitch Timers[ 1]: 1265490528.609078 Here we only have a time-shift of only 1 *microsecond*! Also note that the "glitch" is recovered later on. So it seems that we don't need any "processing magic" at all. Just convert the widgets to continuous timers and make the two changes in "timer.c", and we're set! Actually, I didn't think it was *that* easy, and maybe I have overseen something -- but maybe that's just it! :) Have a nice week-end, Martin -- www.mzuther.de www.radix-musik.de |
From: Michael R. <mi...@re...> - 2010-02-07 05:44:04
|
Hi Martin! > To be honest, I don't... :) Well, I think you're not alone ;-) > First, I think we have to define the problem, because in my opinion there are two of them that need separate solving. > One is the time-shift that is introduced by processing. The other one is that of unsynchronised widgets, and I have > already solved that, at least partially. So let's talk about time-shifts. Correct. > First, using one-shot timers for widgets doesn't seem to make sense to me. First, there is the overhead of deleting > the old one and creating a new one. Second, most (if not all) widgets are triggered regularly, so using one-shot > timers isn't the best solution. That's not true, at least not at all. At the moment, only two o three widgets use one-shot timers, just because the other widgets haven't been ported to use "Properties" yet. A "property" is a widget attribute from the config file, which is evaluated at every update (and not only once when initializing the widget). I'd like to call them "dynamic attributes" because they may change at runtime. A (simple) example would be "update is_night()? 500 : 100" > First, have a look at line 182, which is where a single *continuous* timer is being respawned: > > } else { Timers[i].when = now; timer_inc(&Timers[i].when, Timers[i].interval); } > > I think the second line (which sets the timer to "now") is plain wrong because it automatically delays a timer by the > time the callback needs for processing. So this line should be removed as fast as possible! It took me some time to understand it, but you are absolutely right! > Another, albeit smaller, problem lies in line 206: > > /* delay until next timer event */ struct timeval diff; timersub(&Timers[min].when, &now, &diff); > > delay->tv_sec = diff.tv_sec; /* microseconds to nanoseconds!! */ delay->tv_nsec = diff.tv_usec * 1000; > > Here, the delay to the next timer event is too long, because we ignore the processing time between reading the value > for "now" and calculating the delay. What we need here is to update the value for "now" and only then calculate the > delay: > > /* delay until next timer event */ struct timeval diff; timersub(&Timers[min].when, &now, &diff); gettimeofday(&now, > NULL); Again, you are right. > So it seems that we don't need any "processing magic" at all. Just convert the widgets to continuous timers and make > the two changes in "timer.c", and we're set! Actually, I didn't think it was *that* easy, and maybe I have overseen > something -- but maybe that's just it! :) Great! So the timers should work correctly now, and there should be no mor time-shifts, right? And now for your 2nd mail: > Moreover, I have found out that you don't even have to change any single line in the widget code if you apply the > patch for synchronising widgets I have sent before. I have applied this patch, and now the widgets are synced (at > least within their respective groups) and the timers are correct to the microsecond! I'm afraid I did miss that patch you are mentioning... wasn't it that "timer_group" stuff? Isn't it necessary to replace the timer_add() call in the widget code? > I repeat my old question: shall I commit, or shan't I commit? ;) I can't answer because... (see above) but: if there is no more timeshift, how can widgets get unsync? OTOH: please consider two things: the "initial delay" and the "properties" stuff from above. please, please, don't get me wrong: I in no way dislike your patch. I just want to solve it for *all* timers, not only widget updates. bye, Michael -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Martin Z. <co...@mz...> - 2010-02-06 22:26:51
|
Hi everybody, I have just committed the two small but efficient changes in "timer.c" that I mentioned in my last email. Moreover, I have found out that you don't even have to change any single line in the widget code if you apply the patch for synchronising widgets I have sent before. I have applied this patch, and now the widgets are synced (at least within their respective groups) and the timers are correct to the microsecond! Here's the -- hmmm -- not so short output from a real world example (the LCD control for my media server, to be exact), run for 20 seconds and then sorted by timer id: timer.c: Timer[ 1]: 1265494167.034760 timer.c: Timer[ 1]: 1265494167.134760 timer.c: Timer[ 1]: 1265494167.234760 timer.c: Timer[ 1]: 1265494167.334760 timer.c: Timer[ 1]: 1265494167.434760 timer.c: Timer[ 1]: 1265494167.534760 timer.c: Timer[ 1]: 1265494167.634760 timer.c: Timer[ 1]: 1265494167.734760 timer.c: Timer[ 1]: 1265494167.834760 timer.c: Timer[ 1]: 1265494167.934760 timer.c: Timer[ 1]: 1265494168.034760 timer.c: Timer[ 1]: 1265494168.134760 timer.c: Timer[ 1]: 1265494168.234760 timer.c: Timer[ 1]: 1265494168.334760 timer.c: Timer[ 1]: 1265494168.434760 timer.c: Timer[ 1]: 1265494168.534760 timer.c: Timer[ 1]: 1265494168.634760 timer.c: Timer[ 1]: 1265494168.734760 timer.c: Timer[ 1]: 1265494168.834760 timer.c: Timer[ 1]: 1265494168.934760 timer.c: Timer[ 1]: 1265494169.034760 timer.c: Timer[ 1]: 1265494169.134760 timer.c: Timer[ 1]: 1265494169.234760 timer.c: Timer[ 1]: 1265494169.334760 timer.c: Timer[ 1]: 1265494169.434760 timer.c: Timer[ 1]: 1265494169.534760 timer.c: Timer[ 1]: 1265494169.634760 timer.c: Timer[ 1]: 1265494169.734760 timer.c: Timer[ 1]: 1265494169.834760 timer.c: Timer[ 1]: 1265494169.934760 timer.c: Timer[ 1]: 1265494170.034760 timer.c: Timer[ 1]: 1265494170.134760 timer.c: Timer[ 1]: 1265494170.234760 timer.c: Timer[ 1]: 1265494170.334760 timer.c: Timer[ 1]: 1265494170.434760 timer.c: Timer[ 1]: 1265494170.534760 timer.c: Timer[ 1]: 1265494170.634760 timer.c: Timer[ 1]: 1265494170.734760 timer.c: Timer[ 1]: 1265494170.834760 timer.c: Timer[ 1]: 1265494170.934760 timer.c: Timer[ 1]: 1265494171.034760 timer.c: Timer[ 1]: 1265494171.134760 timer.c: Timer[ 1]: 1265494171.234760 timer.c: Timer[ 1]: 1265494171.334760 timer.c: Timer[ 1]: 1265494171.434760 timer.c: Timer[ 1]: 1265494171.534760 timer.c: Timer[ 1]: 1265494171.634760 timer.c: Timer[ 1]: 1265494171.734760 timer.c: Timer[ 1]: 1265494171.834760 timer.c: Timer[ 1]: 1265494171.934760 timer.c: Timer[ 1]: 1265494172.034760 timer.c: Timer[ 1]: 1265494172.134760 timer.c: Timer[ 1]: 1265494172.234760 timer.c: Timer[ 1]: 1265494172.334760 timer.c: Timer[ 1]: 1265494172.434760 timer.c: Timer[ 1]: 1265494172.534760 timer.c: Timer[ 1]: 1265494172.634760 timer.c: Timer[ 1]: 1265494172.734760 timer.c: Timer[ 1]: 1265494172.834760 timer.c: Timer[ 1]: 1265494172.934760 timer.c: Timer[ 1]: 1265494173.034760 timer.c: Timer[ 1]: 1265494173.134760 timer.c: Timer[ 1]: 1265494173.234760 timer.c: Timer[ 1]: 1265494173.334760 timer.c: Timer[ 1]: 1265494173.434760 timer.c: Timer[ 1]: 1265494173.534760 timer.c: Timer[ 1]: 1265494173.634760 timer.c: Timer[ 1]: 1265494173.734760 timer.c: Timer[ 1]: 1265494173.834760 timer.c: Timer[ 1]: 1265494173.934760 timer.c: Timer[ 1]: 1265494174.034760 timer.c: Timer[ 1]: 1265494174.134760 timer.c: Timer[ 1]: 1265494174.234760 timer.c: Timer[ 1]: 1265494174.334760 timer.c: Timer[ 1]: 1265494174.434760 timer.c: Timer[ 1]: 1265494174.534760 timer.c: Timer[ 1]: 1265494174.634760 timer.c: Timer[ 1]: 1265494174.734760 timer.c: Timer[ 1]: 1265494174.834760 timer.c: Timer[ 1]: 1265494174.934760 timer.c: Timer[ 1]: 1265494175.034760 timer.c: Timer[ 1]: 1265494175.134760 timer.c: Timer[ 1]: 1265494175.234760 timer.c: Timer[ 1]: 1265494175.334760 timer.c: Timer[ 1]: 1265494175.434760 timer.c: Timer[ 1]: 1265494175.534760 timer.c: Timer[ 1]: 1265494175.634760 timer.c: Timer[ 1]: 1265494175.734760 timer.c: Timer[ 1]: 1265494175.834760 timer.c: Timer[ 1]: 1265494175.934760 timer.c: Timer[ 1]: 1265494176.034760 timer.c: Timer[ 1]: 1265494176.134760 timer.c: Timer[ 1]: 1265494176.234760 timer.c: Timer[ 1]: 1265494176.334760 timer.c: Timer[ 1]: 1265494176.434760 timer.c: Timer[ 1]: 1265494176.534760 timer.c: Timer[ 1]: 1265494176.634760 timer.c: Timer[ 1]: 1265494176.734760 timer.c: Timer[ 1]: 1265494176.834760 timer.c: Timer[ 1]: 1265494176.934760 timer.c: Timer[ 1]: 1265494177.034760 timer.c: Timer[ 1]: 1265494177.134760 timer.c: Timer[ 1]: 1265494177.234760 timer.c: Timer[ 1]: 1265494177.334760 timer.c: Timer[ 1]: 1265494177.434760 timer.c: Timer[ 1]: 1265494177.534760 timer.c: Timer[ 1]: 1265494177.634760 timer.c: Timer[ 1]: 1265494177.734760 timer.c: Timer[ 1]: 1265494177.834760 timer.c: Timer[ 1]: 1265494177.934760 timer.c: Timer[ 1]: 1265494178.034760 timer.c: Timer[ 1]: 1265494178.134760 timer.c: Timer[ 1]: 1265494178.234760 timer.c: Timer[ 1]: 1265494178.334760 timer.c: Timer[ 1]: 1265494178.434760 timer.c: Timer[ 1]: 1265494178.534760 timer.c: Timer[ 1]: 1265494178.634760 timer.c: Timer[ 1]: 1265494178.734760 timer.c: Timer[ 1]: 1265494178.834760 timer.c: Timer[ 1]: 1265494178.934760 timer.c: Timer[ 1]: 1265494179.034760 timer.c: Timer[ 1]: 1265494179.134760 timer.c: Timer[ 1]: 1265494179.234760 timer.c: Timer[ 1]: 1265494179.334760 timer.c: Timer[ 1]: 1265494179.434760 timer.c: Timer[ 1]: 1265494179.534760 timer.c: Timer[ 1]: 1265494179.634760 timer.c: Timer[ 1]: 1265494179.734760 timer.c: Timer[ 1]: 1265494179.834760 timer.c: Timer[ 1]: 1265494179.934760 timer.c: Timer[ 1]: 1265494180.034760 timer.c: Timer[ 1]: 1265494180.134760 timer.c: Timer[ 1]: 1265494180.234760 timer.c: Timer[ 1]: 1265494180.334760 timer.c: Timer[ 1]: 1265494180.434760 timer.c: Timer[ 1]: 1265494180.534760 timer.c: Timer[ 1]: 1265494180.634760 timer.c: Timer[ 1]: 1265494180.734760 timer.c: Timer[ 1]: 1265494180.834760 timer.c: Timer[ 1]: 1265494180.934760 timer.c: Timer[ 1]: 1265494181.034760 timer.c: Timer[ 1]: 1265494181.134760 timer.c: Timer[ 1]: 1265494181.234760 timer.c: Timer[ 1]: 1265494181.334760 timer.c: Timer[ 1]: 1265494181.434760 timer.c: Timer[ 1]: 1265494181.534760 timer.c: Timer[ 1]: 1265494181.634760 timer.c: Timer[ 1]: 1265494181.734760 timer.c: Timer[ 1]: 1265494181.834760 timer.c: Timer[ 1]: 1265494181.934760 timer.c: Timer[ 1]: 1265494182.034760 timer.c: Timer[ 1]: 1265494182.134760 timer.c: Timer[ 1]: 1265494182.234760 timer.c: Timer[ 1]: 1265494182.334760 timer.c: Timer[ 1]: 1265494182.434760 timer.c: Timer[ 1]: 1265494182.534760 timer.c: Timer[ 1]: 1265494182.634760 timer.c: Timer[ 1]: 1265494182.734760 timer.c: Timer[ 1]: 1265494182.834760 timer.c: Timer[ 1]: 1265494182.934760 timer.c: Timer[ 1]: 1265494183.034760 timer.c: Timer[ 1]: 1265494183.134760 timer.c: Timer[ 1]: 1265494183.234760 timer.c: Timer[ 1]: 1265494183.334760 timer.c: Timer[ 1]: 1265494183.434760 timer.c: Timer[ 1]: 1265494183.534760 timer.c: Timer[ 1]: 1265494183.634760 timer.c: Timer[ 1]: 1265494183.734760 timer.c: Timer[ 1]: 1265494183.834760 timer.c: Timer[ 1]: 1265494183.934760 timer.c: Timer[ 1]: 1265494184.034760 timer.c: Timer[ 1]: 1265494184.134760 timer.c: Timer[ 1]: 1265494184.234760 timer.c: Timer[ 1]: 1265494184.334760 timer.c: Timer[ 1]: 1265494184.434760 timer.c: Timer[ 1]: 1265494184.534760 timer.c: Timer[ 1]: 1265494184.634760 timer.c: Timer[ 1]: 1265494184.734760 timer.c: Timer[ 1]: 1265494184.834760 timer.c: Timer[ 1]: 1265494184.934760 timer.c: Timer[ 1]: 1265494185.034760 timer.c: Timer[ 1]: 1265494185.134760 timer.c: Timer[ 1]: 1265494185.234760 timer.c: Timer[ 1]: 1265494185.334760 timer.c: Timer[ 1]: 1265494185.434760 timer.c: Timer[ 1]: 1265494185.534760 timer.c: Timer[ 1]: 1265494185.634760 timer.c: Timer[ 1]: 1265494185.734760 timer.c: Timer[ 1]: 1265494185.834760 timer.c: Timer[ 1]: 1265494185.934760 timer.c: Timer[ 1]: 1265494186.034760 timer.c: Timer[ 1]: 1265494186.134760 timer.c: Timer[ 1]: 1265494186.234760 timer.c: Timer[ 1]: 1265494186.334760 timer.c: Timer[ 1]: 1265494186.434760 timer.c: Timer[ 1]: 1265494186.534760 timer.c: Timer[ 1]: 1265494186.634760 timer.c: Timer[ 1]: 1265494186.734760 timer.c: Timer[ 1]: 1265494186.834760 timer.c: Timer[ 1]: 1265494186.934760 timer.c: Timer[ 1]: 1265494187.034760 timer.c: Timer[ 1]: 1265494187.134760 timer.c: Timer[ 1]: 1265494187.234760 timer.c: Timer[ 1]: 1265494187.334760 timer.c: Timer[ 1]: 1265494187.434760 timer.c: Timer[ 1]: 1265494187.534760 timer.c: Timer[ 1]: 1265494187.634760 timer.c: Timer[ 1]: 1265494187.734760 timer.c: Timer[ 1]: 1265494187.834760 timer.c: Timer[ 1]: 1265494187.934760 timer.c: Timer[ 2]: 1265494166.970222 timer.c: Timer[ 2]: 1265494167.220222 timer.c: Timer[ 2]: 1265494167.470222 timer.c: Timer[ 2]: 1265494167.720222 timer.c: Timer[ 2]: 1265494167.970222 timer.c: Timer[ 2]: 1265494168.220222 timer.c: Timer[ 2]: 1265494168.470222 timer.c: Timer[ 2]: 1265494168.720222 timer.c: Timer[ 2]: 1265494168.970222 timer.c: Timer[ 2]: 1265494169.220222 timer.c: Timer[ 2]: 1265494169.470222 timer.c: Timer[ 2]: 1265494169.720222 timer.c: Timer[ 2]: 1265494169.970222 timer.c: Timer[ 2]: 1265494170.220222 timer.c: Timer[ 2]: 1265494170.470222 timer.c: Timer[ 2]: 1265494170.720222 timer.c: Timer[ 2]: 1265494170.970222 timer.c: Timer[ 2]: 1265494171.220222 timer.c: Timer[ 2]: 1265494171.470222 timer.c: Timer[ 2]: 1265494171.720222 timer.c: Timer[ 2]: 1265494171.970222 timer.c: Timer[ 2]: 1265494172.220222 timer.c: Timer[ 2]: 1265494172.470222 timer.c: Timer[ 2]: 1265494172.720222 timer.c: Timer[ 2]: 1265494172.970222 timer.c: Timer[ 2]: 1265494173.220222 timer.c: Timer[ 2]: 1265494173.470222 timer.c: Timer[ 2]: 1265494173.720222 timer.c: Timer[ 2]: 1265494173.970222 timer.c: Timer[ 2]: 1265494174.220222 timer.c: Timer[ 2]: 1265494174.470222 timer.c: Timer[ 2]: 1265494174.720222 timer.c: Timer[ 2]: 1265494174.970222 timer.c: Timer[ 2]: 1265494175.220222 timer.c: Timer[ 2]: 1265494175.470222 timer.c: Timer[ 2]: 1265494175.720222 timer.c: Timer[ 2]: 1265494175.970222 timer.c: Timer[ 2]: 1265494176.220222 timer.c: Timer[ 2]: 1265494176.470222 timer.c: Timer[ 2]: 1265494176.720222 timer.c: Timer[ 2]: 1265494176.970222 timer.c: Timer[ 2]: 1265494177.220222 timer.c: Timer[ 2]: 1265494177.470222 timer.c: Timer[ 2]: 1265494177.720222 timer.c: Timer[ 2]: 1265494177.970222 timer.c: Timer[ 2]: 1265494178.220222 timer.c: Timer[ 2]: 1265494178.470222 timer.c: Timer[ 2]: 1265494178.720222 timer.c: Timer[ 2]: 1265494178.970222 timer.c: Timer[ 2]: 1265494179.220222 timer.c: Timer[ 2]: 1265494179.470222 timer.c: Timer[ 2]: 1265494179.720222 timer.c: Timer[ 2]: 1265494179.970222 timer.c: Timer[ 2]: 1265494180.220222 timer.c: Timer[ 2]: 1265494180.470222 timer.c: Timer[ 2]: 1265494180.720222 timer.c: Timer[ 2]: 1265494180.970222 timer.c: Timer[ 2]: 1265494181.220222 timer.c: Timer[ 2]: 1265494181.470222 timer.c: Timer[ 2]: 1265494181.720222 timer.c: Timer[ 2]: 1265494181.970222 timer.c: Timer[ 2]: 1265494182.220222 timer.c: Timer[ 2]: 1265494182.470222 timer.c: Timer[ 2]: 1265494182.720222 timer.c: Timer[ 2]: 1265494182.970222 timer.c: Timer[ 2]: 1265494183.220222 timer.c: Timer[ 2]: 1265494183.470222 timer.c: Timer[ 2]: 1265494183.720222 timer.c: Timer[ 2]: 1265494183.970222 timer.c: Timer[ 2]: 1265494184.220222 timer.c: Timer[ 2]: 1265494184.470222 timer.c: Timer[ 2]: 1265494184.720222 timer.c: Timer[ 2]: 1265494184.970222 timer.c: Timer[ 2]: 1265494185.220222 timer.c: Timer[ 2]: 1265494185.470222 timer.c: Timer[ 2]: 1265494185.720222 timer.c: Timer[ 2]: 1265494185.970222 timer.c: Timer[ 2]: 1265494186.220222 timer.c: Timer[ 2]: 1265494186.470222 timer.c: Timer[ 2]: 1265494186.720222 timer.c: Timer[ 2]: 1265494186.970222 timer.c: Timer[ 2]: 1265494187.220222 timer.c: Timer[ 2]: 1265494187.470222 timer.c: Timer[ 2]: 1265494187.720222 timer.c: Timer[ 3]: 1265494166.970265 timer.c: Timer[ 3]: 1265494167.220265 timer.c: Timer[ 3]: 1265494167.470265 timer.c: Timer[ 3]: 1265494167.720265 timer.c: Timer[ 3]: 1265494167.970265 timer.c: Timer[ 3]: 1265494168.220265 timer.c: Timer[ 3]: 1265494168.470265 timer.c: Timer[ 3]: 1265494168.720265 timer.c: Timer[ 3]: 1265494168.970265 timer.c: Timer[ 3]: 1265494169.220265 timer.c: Timer[ 3]: 1265494169.470265 timer.c: Timer[ 3]: 1265494169.720265 timer.c: Timer[ 3]: 1265494169.970265 timer.c: Timer[ 3]: 1265494170.220265 timer.c: Timer[ 3]: 1265494170.470265 timer.c: Timer[ 3]: 1265494170.720265 timer.c: Timer[ 3]: 1265494170.970265 timer.c: Timer[ 3]: 1265494171.220265 timer.c: Timer[ 3]: 1265494171.470265 timer.c: Timer[ 3]: 1265494171.720265 timer.c: Timer[ 3]: 1265494171.970265 timer.c: Timer[ 3]: 1265494172.220265 timer.c: Timer[ 3]: 1265494172.470265 timer.c: Timer[ 3]: 1265494172.720265 timer.c: Timer[ 3]: 1265494172.970265 timer.c: Timer[ 3]: 1265494173.220265 timer.c: Timer[ 3]: 1265494173.470265 timer.c: Timer[ 3]: 1265494173.720265 timer.c: Timer[ 3]: 1265494173.970265 timer.c: Timer[ 3]: 1265494174.220265 timer.c: Timer[ 3]: 1265494174.470265 timer.c: Timer[ 3]: 1265494174.720265 timer.c: Timer[ 3]: 1265494174.970265 timer.c: Timer[ 3]: 1265494175.220265 timer.c: Timer[ 3]: 1265494175.470265 timer.c: Timer[ 3]: 1265494175.720265 timer.c: Timer[ 3]: 1265494175.970265 timer.c: Timer[ 3]: 1265494176.220265 timer.c: Timer[ 3]: 1265494176.470265 timer.c: Timer[ 3]: 1265494176.720265 timer.c: Timer[ 3]: 1265494176.970265 timer.c: Timer[ 3]: 1265494177.220265 timer.c: Timer[ 3]: 1265494177.470265 timer.c: Timer[ 3]: 1265494177.720265 timer.c: Timer[ 3]: 1265494177.970265 timer.c: Timer[ 3]: 1265494178.220265 timer.c: Timer[ 3]: 1265494178.470265 timer.c: Timer[ 3]: 1265494178.720265 timer.c: Timer[ 3]: 1265494178.970265 timer.c: Timer[ 3]: 1265494179.220265 timer.c: Timer[ 3]: 1265494179.470265 timer.c: Timer[ 3]: 1265494179.720265 timer.c: Timer[ 3]: 1265494179.970265 timer.c: Timer[ 3]: 1265494180.220265 timer.c: Timer[ 3]: 1265494180.470265 timer.c: Timer[ 3]: 1265494180.720265 timer.c: Timer[ 3]: 1265494180.970265 timer.c: Timer[ 3]: 1265494181.220265 timer.c: Timer[ 3]: 1265494181.470265 timer.c: Timer[ 3]: 1265494181.720265 timer.c: Timer[ 3]: 1265494181.970265 timer.c: Timer[ 3]: 1265494182.220265 timer.c: Timer[ 3]: 1265494182.470265 timer.c: Timer[ 3]: 1265494182.720265 timer.c: Timer[ 3]: 1265494182.970265 timer.c: Timer[ 3]: 1265494183.220265 timer.c: Timer[ 3]: 1265494183.470265 timer.c: Timer[ 3]: 1265494183.720265 timer.c: Timer[ 3]: 1265494183.970265 timer.c: Timer[ 3]: 1265494184.220265 timer.c: Timer[ 3]: 1265494184.470265 timer.c: Timer[ 3]: 1265494184.720265 timer.c: Timer[ 3]: 1265494184.970265 timer.c: Timer[ 3]: 1265494185.220265 timer.c: Timer[ 3]: 1265494185.470265 timer.c: Timer[ 3]: 1265494185.720265 timer.c: Timer[ 3]: 1265494185.970265 timer.c: Timer[ 3]: 1265494186.220265 timer.c: Timer[ 3]: 1265494186.470265 timer.c: Timer[ 3]: 1265494186.720265 timer.c: Timer[ 3]: 1265494186.970265 timer.c: Timer[ 3]: 1265494187.220265 timer.c: Timer[ 3]: 1265494187.470265 timer.c: Timer[ 3]: 1265494187.720265 timer.c: Timer[ 4]: 1265494166.970307 timer.c: Timer[ 4]: 1265494167.220307 timer.c: Timer[ 4]: 1265494167.470307 timer.c: Timer[ 4]: 1265494167.720307 timer.c: Timer[ 4]: 1265494167.970307 timer.c: Timer[ 4]: 1265494168.220307 timer.c: Timer[ 4]: 1265494168.470307 timer.c: Timer[ 4]: 1265494168.720307 timer.c: Timer[ 4]: 1265494168.970307 timer.c: Timer[ 4]: 1265494169.220307 timer.c: Timer[ 4]: 1265494169.470307 timer.c: Timer[ 4]: 1265494169.720307 timer.c: Timer[ 4]: 1265494169.970307 timer.c: Timer[ 4]: 1265494170.220307 timer.c: Timer[ 4]: 1265494170.470307 timer.c: Timer[ 4]: 1265494170.720307 timer.c: Timer[ 4]: 1265494170.970307 timer.c: Timer[ 4]: 1265494171.220307 timer.c: Timer[ 4]: 1265494171.470307 timer.c: Timer[ 4]: 1265494171.720307 timer.c: Timer[ 4]: 1265494171.970307 timer.c: Timer[ 4]: 1265494172.220307 timer.c: Timer[ 4]: 1265494172.470307 timer.c: Timer[ 4]: 1265494172.720307 timer.c: Timer[ 4]: 1265494172.970307 timer.c: Timer[ 4]: 1265494173.220307 timer.c: Timer[ 4]: 1265494173.470307 timer.c: Timer[ 4]: 1265494173.720307 timer.c: Timer[ 4]: 1265494173.970307 timer.c: Timer[ 4]: 1265494174.220307 timer.c: Timer[ 4]: 1265494174.470307 timer.c: Timer[ 4]: 1265494174.720307 timer.c: Timer[ 4]: 1265494174.970307 timer.c: Timer[ 4]: 1265494175.220307 timer.c: Timer[ 4]: 1265494175.470307 timer.c: Timer[ 4]: 1265494175.720307 timer.c: Timer[ 4]: 1265494175.970307 timer.c: Timer[ 4]: 1265494176.220307 timer.c: Timer[ 4]: 1265494176.470307 timer.c: Timer[ 4]: 1265494176.720307 timer.c: Timer[ 4]: 1265494176.970307 timer.c: Timer[ 4]: 1265494177.220307 timer.c: Timer[ 4]: 1265494177.470307 timer.c: Timer[ 4]: 1265494177.720307 timer.c: Timer[ 4]: 1265494177.970307 timer.c: Timer[ 4]: 1265494178.220307 timer.c: Timer[ 4]: 1265494178.470307 timer.c: Timer[ 4]: 1265494178.720307 timer.c: Timer[ 4]: 1265494178.970307 timer.c: Timer[ 4]: 1265494179.220307 timer.c: Timer[ 4]: 1265494179.470307 timer.c: Timer[ 4]: 1265494179.720307 timer.c: Timer[ 4]: 1265494179.970307 timer.c: Timer[ 4]: 1265494180.220307 timer.c: Timer[ 4]: 1265494180.470307 timer.c: Timer[ 4]: 1265494180.720307 timer.c: Timer[ 4]: 1265494180.970307 timer.c: Timer[ 4]: 1265494181.220307 timer.c: Timer[ 4]: 1265494181.470307 timer.c: Timer[ 4]: 1265494181.720307 timer.c: Timer[ 4]: 1265494181.970307 timer.c: Timer[ 4]: 1265494182.220307 timer.c: Timer[ 4]: 1265494182.470307 timer.c: Timer[ 4]: 1265494182.720307 timer.c: Timer[ 4]: 1265494182.970307 timer.c: Timer[ 4]: 1265494183.220307 timer.c: Timer[ 4]: 1265494183.470307 timer.c: Timer[ 4]: 1265494183.720307 timer.c: Timer[ 4]: 1265494183.970307 timer.c: Timer[ 4]: 1265494184.220307 timer.c: Timer[ 4]: 1265494184.470307 timer.c: Timer[ 4]: 1265494184.720307 timer.c: Timer[ 4]: 1265494184.970307 timer.c: Timer[ 4]: 1265494185.220307 timer.c: Timer[ 4]: 1265494185.470307 timer.c: Timer[ 4]: 1265494185.720307 timer.c: Timer[ 4]: 1265494185.970307 timer.c: Timer[ 4]: 1265494186.220307 timer.c: Timer[ 4]: 1265494186.470307 timer.c: Timer[ 4]: 1265494186.720307 timer.c: Timer[ 4]: 1265494186.970307 timer.c: Timer[ 4]: 1265494187.220307 timer.c: Timer[ 4]: 1265494187.470307 timer.c: Timer[ 4]: 1265494187.720307 timer.c: Timer[ 5]: 1265494166.970349 timer.c: Timer[ 5]: 1265494167.220349 timer.c: Timer[ 5]: 1265494167.470349 timer.c: Timer[ 5]: 1265494167.720349 timer.c: Timer[ 5]: 1265494167.970349 timer.c: Timer[ 5]: 1265494168.220349 timer.c: Timer[ 5]: 1265494168.470349 timer.c: Timer[ 5]: 1265494168.720349 timer.c: Timer[ 5]: 1265494168.970349 timer.c: Timer[ 5]: 1265494169.220349 timer.c: Timer[ 5]: 1265494169.470349 timer.c: Timer[ 5]: 1265494169.720349 timer.c: Timer[ 5]: 1265494169.970349 timer.c: Timer[ 5]: 1265494170.220349 timer.c: Timer[ 5]: 1265494170.470349 timer.c: Timer[ 5]: 1265494170.720349 timer.c: Timer[ 5]: 1265494170.970349 timer.c: Timer[ 5]: 1265494171.220349 timer.c: Timer[ 5]: 1265494171.470349 timer.c: Timer[ 5]: 1265494171.720349 timer.c: Timer[ 5]: 1265494171.970349 timer.c: Timer[ 5]: 1265494172.220349 timer.c: Timer[ 5]: 1265494172.470349 timer.c: Timer[ 5]: 1265494172.720349 timer.c: Timer[ 5]: 1265494172.970349 timer.c: Timer[ 5]: 1265494173.220349 timer.c: Timer[ 5]: 1265494173.470349 timer.c: Timer[ 5]: 1265494173.720349 timer.c: Timer[ 5]: 1265494173.970349 timer.c: Timer[ 5]: 1265494174.220349 timer.c: Timer[ 5]: 1265494174.470349 timer.c: Timer[ 5]: 1265494174.720349 timer.c: Timer[ 5]: 1265494174.970349 timer.c: Timer[ 5]: 1265494175.220349 timer.c: Timer[ 5]: 1265494175.470349 timer.c: Timer[ 5]: 1265494175.720349 timer.c: Timer[ 5]: 1265494175.970349 timer.c: Timer[ 5]: 1265494176.220349 timer.c: Timer[ 5]: 1265494176.470349 timer.c: Timer[ 5]: 1265494176.720349 timer.c: Timer[ 5]: 1265494176.970349 timer.c: Timer[ 5]: 1265494177.220349 timer.c: Timer[ 5]: 1265494177.470349 timer.c: Timer[ 5]: 1265494177.720349 timer.c: Timer[ 5]: 1265494177.970349 timer.c: Timer[ 5]: 1265494178.220349 timer.c: Timer[ 5]: 1265494178.470349 timer.c: Timer[ 5]: 1265494178.720349 timer.c: Timer[ 5]: 1265494178.970349 timer.c: Timer[ 5]: 1265494179.220349 timer.c: Timer[ 5]: 1265494179.470349 timer.c: Timer[ 5]: 1265494179.720349 timer.c: Timer[ 5]: 1265494179.970349 timer.c: Timer[ 5]: 1265494180.220349 timer.c: Timer[ 5]: 1265494180.470349 timer.c: Timer[ 5]: 1265494180.720349 timer.c: Timer[ 5]: 1265494180.970349 timer.c: Timer[ 5]: 1265494181.220349 timer.c: Timer[ 5]: 1265494181.470349 timer.c: Timer[ 5]: 1265494181.720349 timer.c: Timer[ 5]: 1265494181.970349 timer.c: Timer[ 5]: 1265494182.220349 timer.c: Timer[ 5]: 1265494182.470349 timer.c: Timer[ 5]: 1265494182.720349 timer.c: Timer[ 5]: 1265494182.970349 timer.c: Timer[ 5]: 1265494183.220349 timer.c: Timer[ 5]: 1265494183.470349 timer.c: Timer[ 5]: 1265494183.720349 timer.c: Timer[ 5]: 1265494183.970349 timer.c: Timer[ 5]: 1265494184.220349 timer.c: Timer[ 5]: 1265494184.470349 timer.c: Timer[ 5]: 1265494184.720349 timer.c: Timer[ 5]: 1265494184.970349 timer.c: Timer[ 5]: 1265494185.220349 timer.c: Timer[ 5]: 1265494185.470349 timer.c: Timer[ 5]: 1265494185.720349 timer.c: Timer[ 5]: 1265494185.970349 timer.c: Timer[ 5]: 1265494186.220349 timer.c: Timer[ 5]: 1265494186.470349 timer.c: Timer[ 5]: 1265494186.720349 timer.c: Timer[ 5]: 1265494186.970349 timer.c: Timer[ 5]: 1265494187.220349 timer.c: Timer[ 5]: 1265494187.470349 timer.c: Timer[ 5]: 1265494187.720349 timer.c: Timer[ 6]: 1265494166.970390 timer.c: Timer[ 6]: 1265494167.220390 timer.c: Timer[ 6]: 1265494167.470390 timer.c: Timer[ 6]: 1265494167.720390 timer.c: Timer[ 6]: 1265494167.970390 timer.c: Timer[ 6]: 1265494168.220390 timer.c: Timer[ 6]: 1265494168.470390 timer.c: Timer[ 6]: 1265494168.720390 timer.c: Timer[ 6]: 1265494168.970390 timer.c: Timer[ 6]: 1265494169.220390 timer.c: Timer[ 6]: 1265494169.470390 timer.c: Timer[ 6]: 1265494169.720390 timer.c: Timer[ 6]: 1265494169.970390 timer.c: Timer[ 6]: 1265494170.220390 timer.c: Timer[ 6]: 1265494170.470390 timer.c: Timer[ 6]: 1265494170.720390 timer.c: Timer[ 6]: 1265494170.970390 timer.c: Timer[ 6]: 1265494171.220390 timer.c: Timer[ 6]: 1265494171.470390 timer.c: Timer[ 6]: 1265494171.720390 timer.c: Timer[ 6]: 1265494171.970390 timer.c: Timer[ 6]: 1265494172.220390 timer.c: Timer[ 6]: 1265494172.470390 timer.c: Timer[ 6]: 1265494172.720390 timer.c: Timer[ 6]: 1265494172.970390 timer.c: Timer[ 6]: 1265494173.220390 timer.c: Timer[ 6]: 1265494173.470390 timer.c: Timer[ 6]: 1265494173.720390 timer.c: Timer[ 6]: 1265494173.970390 timer.c: Timer[ 6]: 1265494174.220390 timer.c: Timer[ 6]: 1265494174.470390 timer.c: Timer[ 6]: 1265494174.720390 timer.c: Timer[ 6]: 1265494174.970390 timer.c: Timer[ 6]: 1265494175.220390 timer.c: Timer[ 6]: 1265494175.470390 timer.c: Timer[ 6]: 1265494175.720390 timer.c: Timer[ 6]: 1265494175.970390 timer.c: Timer[ 6]: 1265494176.220390 timer.c: Timer[ 6]: 1265494176.470390 timer.c: Timer[ 6]: 1265494176.720390 timer.c: Timer[ 6]: 1265494176.970390 timer.c: Timer[ 6]: 1265494177.220390 timer.c: Timer[ 6]: 1265494177.470390 timer.c: Timer[ 6]: 1265494177.720390 timer.c: Timer[ 6]: 1265494177.970390 timer.c: Timer[ 6]: 1265494178.220390 timer.c: Timer[ 6]: 1265494178.470390 timer.c: Timer[ 6]: 1265494178.720390 timer.c: Timer[ 6]: 1265494178.970390 timer.c: Timer[ 6]: 1265494179.220390 timer.c: Timer[ 6]: 1265494179.470390 timer.c: Timer[ 6]: 1265494179.720390 timer.c: Timer[ 6]: 1265494179.970390 timer.c: Timer[ 6]: 1265494180.220390 timer.c: Timer[ 6]: 1265494180.470390 timer.c: Timer[ 6]: 1265494180.720390 timer.c: Timer[ 6]: 1265494180.970390 timer.c: Timer[ 6]: 1265494181.220390 timer.c: Timer[ 6]: 1265494181.470390 timer.c: Timer[ 6]: 1265494181.720390 timer.c: Timer[ 6]: 1265494181.970390 timer.c: Timer[ 6]: 1265494182.220390 timer.c: Timer[ 6]: 1265494182.470390 timer.c: Timer[ 6]: 1265494182.720390 timer.c: Timer[ 6]: 1265494182.970390 timer.c: Timer[ 6]: 1265494183.220390 timer.c: Timer[ 6]: 1265494183.470390 timer.c: Timer[ 6]: 1265494183.720390 timer.c: Timer[ 6]: 1265494183.970390 timer.c: Timer[ 6]: 1265494184.220390 timer.c: Timer[ 6]: 1265494184.470390 timer.c: Timer[ 6]: 1265494184.720390 timer.c: Timer[ 6]: 1265494184.970390 timer.c: Timer[ 6]: 1265494185.220390 timer.c: Timer[ 6]: 1265494185.470390 timer.c: Timer[ 6]: 1265494185.720390 timer.c: Timer[ 6]: 1265494185.970390 timer.c: Timer[ 6]: 1265494186.220390 timer.c: Timer[ 6]: 1265494186.470390 timer.c: Timer[ 6]: 1265494186.720390 timer.c: Timer[ 6]: 1265494186.970390 timer.c: Timer[ 6]: 1265494187.220390 timer.c: Timer[ 6]: 1265494187.470390 timer.c: Timer[ 6]: 1265494187.720390 timer.c: Timer[ 7]: 1265494166.970435 timer.c: Timer[ 7]: 1265494167.220435 timer.c: Timer[ 7]: 1265494167.470435 timer.c: Timer[ 7]: 1265494167.720435 timer.c: Timer[ 7]: 1265494167.970435 timer.c: Timer[ 7]: 1265494168.220435 timer.c: Timer[ 7]: 1265494168.470435 timer.c: Timer[ 7]: 1265494168.720435 timer.c: Timer[ 7]: 1265494168.970435 timer.c: Timer[ 7]: 1265494169.220435 timer.c: Timer[ 7]: 1265494169.470435 timer.c: Timer[ 7]: 1265494169.720435 timer.c: Timer[ 7]: 1265494169.970435 timer.c: Timer[ 7]: 1265494170.220435 timer.c: Timer[ 7]: 1265494170.470435 timer.c: Timer[ 7]: 1265494170.720435 timer.c: Timer[ 7]: 1265494170.970435 timer.c: Timer[ 7]: 1265494171.220435 timer.c: Timer[ 7]: 1265494171.470435 timer.c: Timer[ 7]: 1265494171.720435 timer.c: Timer[ 7]: 1265494171.970435 timer.c: Timer[ 7]: 1265494172.220435 timer.c: Timer[ 7]: 1265494172.470435 timer.c: Timer[ 7]: 1265494172.720435 timer.c: Timer[ 7]: 1265494172.970435 timer.c: Timer[ 7]: 1265494173.220435 timer.c: Timer[ 7]: 1265494173.470435 timer.c: Timer[ 7]: 1265494173.720435 timer.c: Timer[ 7]: 1265494173.970435 timer.c: Timer[ 7]: 1265494174.220435 timer.c: Timer[ 7]: 1265494174.470435 timer.c: Timer[ 7]: 1265494174.720435 timer.c: Timer[ 7]: 1265494174.970435 timer.c: Timer[ 7]: 1265494175.220435 timer.c: Timer[ 7]: 1265494175.470435 timer.c: Timer[ 7]: 1265494175.720435 timer.c: Timer[ 7]: 1265494175.970435 timer.c: Timer[ 7]: 1265494176.220435 timer.c: Timer[ 7]: 1265494176.470435 timer.c: Timer[ 7]: 1265494176.720435 timer.c: Timer[ 7]: 1265494176.970435 timer.c: Timer[ 7]: 1265494177.220435 timer.c: Timer[ 7]: 1265494177.470435 timer.c: Timer[ 7]: 1265494177.720435 timer.c: Timer[ 7]: 1265494177.970435 timer.c: Timer[ 7]: 1265494178.220435 timer.c: Timer[ 7]: 1265494178.470435 timer.c: Timer[ 7]: 1265494178.720435 timer.c: Timer[ 7]: 1265494178.970435 timer.c: Timer[ 7]: 1265494179.220435 timer.c: Timer[ 7]: 1265494179.470435 timer.c: Timer[ 7]: 1265494179.720435 timer.c: Timer[ 7]: 1265494179.970435 timer.c: Timer[ 7]: 1265494180.220435 timer.c: Timer[ 7]: 1265494180.470435 timer.c: Timer[ 7]: 1265494180.720435 timer.c: Timer[ 7]: 1265494180.970435 timer.c: Timer[ 7]: 1265494181.220435 timer.c: Timer[ 7]: 1265494181.470435 timer.c: Timer[ 7]: 1265494181.720435 timer.c: Timer[ 7]: 1265494181.970435 timer.c: Timer[ 7]: 1265494182.220435 timer.c: Timer[ 7]: 1265494182.470435 timer.c: Timer[ 7]: 1265494182.720435 timer.c: Timer[ 7]: 1265494182.970435 timer.c: Timer[ 7]: 1265494183.220435 timer.c: Timer[ 7]: 1265494183.470435 timer.c: Timer[ 7]: 1265494183.720435 timer.c: Timer[ 7]: 1265494183.970435 timer.c: Timer[ 7]: 1265494184.220435 timer.c: Timer[ 7]: 1265494184.470435 timer.c: Timer[ 7]: 1265494184.720435 timer.c: Timer[ 7]: 1265494184.970435 timer.c: Timer[ 7]: 1265494185.220435 timer.c: Timer[ 7]: 1265494185.470435 timer.c: Timer[ 7]: 1265494185.720435 timer.c: Timer[ 7]: 1265494185.970435 timer.c: Timer[ 7]: 1265494186.220435 timer.c: Timer[ 7]: 1265494186.470435 timer.c: Timer[ 7]: 1265494186.720435 timer.c: Timer[ 7]: 1265494186.970435 timer.c: Timer[ 7]: 1265494187.220435 timer.c: Timer[ 7]: 1265494187.470435 timer.c: Timer[ 7]: 1265494187.720435 timer.c: Timer[ 8]: 1265494166.970481 timer.c: Timer[ 8]: 1265494167.220481 timer.c: Timer[ 8]: 1265494167.470481 timer.c: Timer[ 8]: 1265494167.720481 timer.c: Timer[ 8]: 1265494167.970481 timer.c: Timer[ 8]: 1265494168.220481 timer.c: Timer[ 8]: 1265494168.470481 timer.c: Timer[ 8]: 1265494168.720481 timer.c: Timer[ 8]: 1265494168.970481 timer.c: Timer[ 8]: 1265494169.220481 timer.c: Timer[ 8]: 1265494169.470481 timer.c: Timer[ 8]: 1265494169.720481 timer.c: Timer[ 8]: 1265494169.970481 timer.c: Timer[ 8]: 1265494170.220481 timer.c: Timer[ 8]: 1265494170.470481 timer.c: Timer[ 8]: 1265494170.720481 timer.c: Timer[ 8]: 1265494170.970481 timer.c: Timer[ 8]: 1265494171.220481 timer.c: Timer[ 8]: 1265494171.470481 timer.c: Timer[ 8]: 1265494171.720481 timer.c: Timer[ 8]: 1265494171.970481 timer.c: Timer[ 8]: 1265494172.220481 timer.c: Timer[ 8]: 1265494172.470481 timer.c: Timer[ 8]: 1265494172.720481 timer.c: Timer[ 8]: 1265494172.970481 timer.c: Timer[ 8]: 1265494173.220481 timer.c: Timer[ 8]: 1265494173.470481 timer.c: Timer[ 8]: 1265494173.720481 timer.c: Timer[ 8]: 1265494173.970481 timer.c: Timer[ 8]: 1265494174.220481 timer.c: Timer[ 8]: 1265494174.470481 timer.c: Timer[ 8]: 1265494174.720481 timer.c: Timer[ 8]: 1265494174.970481 timer.c: Timer[ 8]: 1265494175.220481 timer.c: Timer[ 8]: 1265494175.470481 timer.c: Timer[ 8]: 1265494175.720481 timer.c: Timer[ 8]: 1265494175.970481 timer.c: Timer[ 8]: 1265494176.220481 timer.c: Timer[ 8]: 1265494176.470481 timer.c: Timer[ 8]: 1265494176.720481 timer.c: Timer[ 8]: 1265494176.970481 timer.c: Timer[ 8]: 1265494177.220481 timer.c: Timer[ 8]: 1265494177.470481 timer.c: Timer[ 8]: 1265494177.720481 timer.c: Timer[ 8]: 1265494177.970481 timer.c: Timer[ 8]: 1265494178.220481 timer.c: Timer[ 8]: 1265494178.470481 timer.c: Timer[ 8]: 1265494178.720481 timer.c: Timer[ 8]: 1265494178.970481 timer.c: Timer[ 8]: 1265494179.220481 timer.c: Timer[ 8]: 1265494179.470481 timer.c: Timer[ 8]: 1265494179.720481 timer.c: Timer[ 8]: 1265494179.970481 timer.c: Timer[ 8]: 1265494180.220481 timer.c: Timer[ 8]: 1265494180.470481 timer.c: Timer[ 8]: 1265494180.720481 timer.c: Timer[ 8]: 1265494180.970481 timer.c: Timer[ 8]: 1265494181.220481 timer.c: Timer[ 8]: 1265494181.470481 timer.c: Timer[ 8]: 1265494181.720481 timer.c: Timer[ 8]: 1265494181.970481 timer.c: Timer[ 8]: 1265494182.220481 timer.c: Timer[ 8]: 1265494182.470481 timer.c: Timer[ 8]: 1265494182.720481 timer.c: Timer[ 8]: 1265494182.970481 timer.c: Timer[ 8]: 1265494183.220481 timer.c: Timer[ 8]: 1265494183.470481 timer.c: Timer[ 8]: 1265494183.720481 timer.c: Timer[ 8]: 1265494183.970481 timer.c: Timer[ 8]: 1265494184.220481 timer.c: Timer[ 8]: 1265494184.470481 timer.c: Timer[ 8]: 1265494184.720481 timer.c: Timer[ 8]: 1265494184.970481 timer.c: Timer[ 8]: 1265494185.220481 timer.c: Timer[ 8]: 1265494185.470481 timer.c: Timer[ 8]: 1265494185.720481 timer.c: Timer[ 8]: 1265494185.970481 timer.c: Timer[ 8]: 1265494186.220481 timer.c: Timer[ 8]: 1265494186.470481 timer.c: Timer[ 8]: 1265494186.720481 timer.c: Timer[ 8]: 1265494186.970481 timer.c: Timer[ 8]: 1265494187.220481 timer.c: Timer[ 8]: 1265494187.470481 timer.c: Timer[ 8]: 1265494187.720481 timer.c: Timer[ 9]: 1265494166.970578 timer.c: Timer[ 9]: 1265494167.220578 timer.c: Timer[ 9]: 1265494167.470578 timer.c: Timer[ 9]: 1265494167.720578 timer.c: Timer[ 9]: 1265494167.970578 timer.c: Timer[ 9]: 1265494168.220578 timer.c: Timer[ 9]: 1265494168.470578 timer.c: Timer[ 9]: 1265494168.720578 timer.c: Timer[ 9]: 1265494168.970578 timer.c: Timer[ 9]: 1265494169.220578 timer.c: Timer[ 9]: 1265494169.470578 timer.c: Timer[ 9]: 1265494169.720578 timer.c: Timer[ 9]: 1265494169.970578 timer.c: Timer[ 9]: 1265494170.220578 timer.c: Timer[ 9]: 1265494170.470578 timer.c: Timer[ 9]: 1265494170.720578 timer.c: Timer[ 9]: 1265494170.970578 timer.c: Timer[ 9]: 1265494171.220578 timer.c: Timer[ 9]: 1265494171.470578 timer.c: Timer[ 9]: 1265494171.720578 timer.c: Timer[ 9]: 1265494171.970578 timer.c: Timer[ 9]: 1265494172.220578 timer.c: Timer[ 9]: 1265494172.470578 timer.c: Timer[ 9]: 1265494172.720578 timer.c: Timer[ 9]: 1265494172.970578 timer.c: Timer[ 9]: 1265494173.220578 timer.c: Timer[ 9]: 1265494173.470578 timer.c: Timer[ 9]: 1265494173.720578 timer.c: Timer[ 9]: 1265494173.970578 timer.c: Timer[ 9]: 1265494174.220578 timer.c: Timer[ 9]: 1265494174.470578 timer.c: Timer[ 9]: 1265494174.720578 timer.c: Timer[ 9]: 1265494174.970578 timer.c: Timer[ 9]: 1265494175.220578 timer.c: Timer[ 9]: 1265494175.470578 timer.c: Timer[ 9]: 1265494175.720578 timer.c: Timer[ 9]: 1265494175.970578 timer.c: Timer[ 9]: 1265494176.220578 timer.c: Timer[ 9]: 1265494176.470578 timer.c: Timer[ 9]: 1265494176.720578 timer.c: Timer[ 9]: 1265494176.970578 timer.c: Timer[ 9]: 1265494177.220578 timer.c: Timer[ 9]: 1265494177.470578 timer.c: Timer[ 9]: 1265494177.720578 timer.c: Timer[ 9]: 1265494177.970578 timer.c: Timer[ 9]: 1265494178.220578 timer.c: Timer[ 9]: 1265494178.470578 timer.c: Timer[ 9]: 1265494178.720578 timer.c: Timer[ 9]: 1265494178.970578 timer.c: Timer[ 9]: 1265494179.220578 timer.c: Timer[ 9]: 1265494179.470578 timer.c: Timer[ 9]: 1265494179.720578 timer.c: Timer[ 9]: 1265494179.970578 timer.c: Timer[ 9]: 1265494180.220578 timer.c: Timer[ 9]: 1265494180.470578 timer.c: Timer[ 9]: 1265494180.720578 timer.c: Timer[ 9]: 1265494180.970578 timer.c: Timer[ 9]: 1265494181.220578 timer.c: Timer[ 9]: 1265494181.470578 timer.c: Timer[ 9]: 1265494181.720578 timer.c: Timer[ 9]: 1265494181.970578 timer.c: Timer[ 9]: 1265494182.220578 timer.c: Timer[ 9]: 1265494182.470578 timer.c: Timer[ 9]: 1265494182.720578 timer.c: Timer[ 9]: 1265494182.970578 timer.c: Timer[ 9]: 1265494183.220578 timer.c: Timer[ 9]: 1265494183.470578 timer.c: Timer[ 9]: 1265494183.720578 timer.c: Timer[ 9]: 1265494183.970578 timer.c: Timer[ 9]: 1265494184.220578 timer.c: Timer[ 9]: 1265494184.470578 timer.c: Timer[ 9]: 1265494184.720578 timer.c: Timer[ 9]: 1265494184.970578 timer.c: Timer[ 9]: 1265494185.220578 timer.c: Timer[ 9]: 1265494185.470578 timer.c: Timer[ 9]: 1265494185.720578 timer.c: Timer[ 9]: 1265494185.970578 timer.c: Timer[ 9]: 1265494186.220578 timer.c: Timer[ 9]: 1265494186.470578 timer.c: Timer[ 9]: 1265494186.720578 timer.c: Timer[ 9]: 1265494186.970578 timer.c: Timer[ 9]: 1265494187.220578 timer.c: Timer[ 9]: 1265494187.470578 timer.c: Timer[ 9]: 1265494187.720578 May I draw your attention to the last digits? And no, this is not faked... :) I repeat my old question: shall I commit, or shan't I commit? ;) Best regards, Martin -- www.mzuther.de www.radix-musik.de |
From: Michael R. <mi...@re...> - 2010-02-07 05:52:02
|
Hi Martin! another thing came to my mind: your patches will not help getting one-shot timers to go out of sync? As we are basically increasing the timeout value of a timer, and compensate processing delays, this won't work for one-shot timers, because there is nothing to increase... If we want to keep the "dynamic update values" which can be changed at runtime (and I think I want to), maybe a "timer_mod()" function to set a new update interval would solve this? (and avoid the overhead to delete and recreate the timer) bye, Michael -- Michael Reinelt <mi...@re...> http://home.pages.at/reinelt GPG-Key 0xDF13BA50 ICQ #288386781 |
From: Martin Z. <co...@mz...> - 2010-02-07 14:09:36
|
Hi Michael, you're still a little hesitant (and I can understand that), but I'll get you in the end. :) Thanks -- I have finally understood where all the one-shot timers come from. I never had the time to more than glance at the widget code. But couldn't the "dynamic value update" (which is great and I want to keep as well!) somehow be done during the update callback function? Anyway, yesterday I *did* write some code to sync all timers. What it does is (again) easy but works quite well. When the first timer is started, a global timeval called "timer_sync_base" is set to the current date and time by gettimeofday(). After that, this global value is never touched again. Now, when a new timer is added, my code calculates the number of updates that have happened since "timer_sync_base" and also the time difference that corresponds to this number of updates. This time difference is then added to "timer_sync_base", and finally the timer's "update" value is set to the result. I think, an example is in order (to keep it easy, update interval is one second): 1265490677.167110 first timer is added "timer_sync_base" is set to 1265490677.167110 timer variable "update" is set to 1265490677.167110 1265490678.171091 first timer triggers (initialisation; this is your "old" code) 1265490678.167110 first timer triggers (one second since timer base) 1265490678.671346 second timer is added code calculates that one update has already passed timer variable "update" is set to 1265490678.167110 (one second after "timer_sync_base") 1265490678.698234 second timer triggers (intialisation; this again is your "old" code) 1265490679.167110 first timer triggers (two seconds since timer base) 1265490679.167110 second timer triggers (two seconds since timer base) I have found some easy mathematics to calculate the number of passed updates, so this does not interfere with performance. The code works, but it needs cleaning up and commenting. Right now, I'm probably the only one who'd understand it. ;) > I'm afraid I did miss that patch you are mentioning... wasn't it that "timer_group" stuff? Isn't it necessary to replace > the timer_add() call in the widget code? Yes, that's the one I meant. While you don't exactly need this grouping of timers, it *does* reduce overhead by creating only one timer per group, and this group timer is even continuous. The timer_add() call in the widget code would have to be changed to timer_add_widget(), of course, but the widgets do keep their one-shot timers. So as I said, the widget code wouldn't have to change at all, but we'd get rid of all the one-shot-timer overhead. As a side effect, the groups also ensure that all widgets in a group are updated simultaneously. This effect could also be used for LCDs that only write to a framebuffer and are then updated as a whole, because you could implement a function called update_all() that would be called after all widgets within a group have been updated. This function would have to be in all drivers and would usually be empty. But in drivers that update the whole display, this function would then write the frame buffer to the LCD, getting rid of the timer that is currently needed to regularly copy the frame buffer to the display. You see, I have put some thought into all this, because my LCD is *really* slow when it is updated... :) Given all these advantages, I have finally committed my patch for grouping widgets. I don't know if I've got the copyrights correct -- please feel free to correct them. > but: if there is no more timeshift, how can widgets get unsync? Yes, you're right (if there is no initial delay, but as I say, I'm on my way to fixing this). I think there might be problems with the overhead of creating all those one-shot timers, but I'm in no way able to describe them. Let's say, they are similar to a foreboding... ;) > please, please, don't get me wrong: I in no way dislike your patch. I just want to solve it for *all* timers, not only > widget updates. I didn't get you wrong at all. I know what you're driving at, and I think we're on our way to solve the problem. :) Greetings from snowy Hamburg, Martin -- www.mzuther.de www.radix-musik.de |
From: Martin Z. <co...@mz...> - 2010-02-09 20:22:32
|
Hi everybody, I have finally implemented and commented the code for syncing all timers. To make it more useful, I have placed this code in timer_inc(), which is now: static void timer_inc( struct timeval *timer, const struct timeval *now, const int interval, const short calculate_upcoming_event) The function is used to calculate the starting point of newly added timers and also to calculate the next triggering event for existing timers. I have tried to describe this behaviour in my last email. In short, it records the moment the first timer was started within "lcd4linux". Then, it uses this moment to quantise timer events using a timer's update interval: first timer: v second timer: * * * * * * quantisation: +---+---+---+---+---+---+--- second timer: * * * * * * This get's rid of the last synching problem, the differences in starting delay. For example, if you have to widgets with update intervals of 250 ms and 500 ms, respectively, you often got: 250 ms: * * * * * * * * * * * * 500 ms: * * * * * * Now you they are completely in sync: 250 ms: * * * * * * * * * * * * 500 ms: * * * * * * As a side note, the parameter "calculate_upcoming_event" is used to tell timer_inc() whether it should calculate the last time the timer triggered or the next time the timer will be triggered. This is all a bit hard to explain, but I hope that I gave you at least an idea of what I'm talking about. The new implementation of timer_inc() has one "problem" though: if you add a timer, the delay to first triggering event will usually be less than its update time. For example, if you add a timer of 400 ms, it might already trigger after 235 ms (afterwards, it will of course stick to the 400 ms). This is needed for quantisation and thus synchronisation of the timers, but I don't know if anybody needs "unsynched" timers that trigger *exactly* after the update time has passed. Which is the reason why I haven't yet committed my code. Actually, this is somewhat theoretical, because when I'm talking of "timing to the microsecond", I mean the times a timer *should* trigger, not the times it *does* trigger. This depends on things we can't influence, such as CPU utilisation and the time widgets need for updating. If you didn't get what the heck I'm talking about, please complain. Otherwise, tell me whether you see a need for "unsynched" timers or not. :) Thanks, Martin -- www.mzuther.de www.radix-musik.de |