[<<] [<] Page 1 of 1 [>] [>>] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
An average accurate periodic timer
From: Chen sheng ####@####.#### Date: 28 Aug 2002 06:29:22 -0000 Message-Id: <20020828062854.16759.qmail@web9907.mail.yahoo.com> Hi, Let us consider two situations where current periodic timer is not accurate. Situation 1 If we create a periodic timer with period not a multiple of 10ms, say 25ms, GrCreateTimer(wid, 25, GR_TRUE); we expect there will be 40 timer events come from server in 1 second. But in fact it is not true, because the system timer resolution is 10ms. The above statement is equivalent to GrCreateTimer(wid, 30, GR_TRUE); Situation 2 If the system is busy executing some other processes, so that the NanoX server is suspended for 100ms, then a few timer events are lost. What I want from periodic timer is, although each timer event may not arrives accurately, the average time should be accurate. That is to say, there should be exactly 40 timer events come from server in 1 second if the timer period is 25ms. To solve this problem, I modify slightly the way to calculate new timeout value. Instead of base on current time, I calculate it base on old timeout value. Please see the patch below. I believe it is not of gerenal interest. But it is useful to me. Regards, Sheng --- microwin-aph/src/engine/devtimer.c Mon Apr 8 10:30:18 2002 +++ microwin-aph-new/src/engine/devtimer.c Wed Aug 28 09:34:31 2002 @@ -65,6 +65,7 @@ static struct timeval current_time; static void calculate_timeval(struct timeval *tv, MWTIMEOUT to); +static void calculate_timeval_strict(struct timeval *tv, MWTIMEOUT to); static signed long time_to_expiry(struct timeval *t); MWTIMER *GdAddTimer(MWTIMEOUT timeout, MWTIMERCB callback, void *arg, @@ -159,7 +160,7 @@ if(time_to_expiry(&t->timeout) <= 0) { t->callback(t->arg); if(!t->periodic) GdDestroyTimer(t); - else calculate_timeval(&t->timeout, t->period); + else calculate_timeval_strict(&t->timeout, t->period); } t = n; } @@ -175,6 +176,16 @@ { tv->tv_sec = current_time.tv_sec + (to / 1000); tv->tv_usec = current_time.tv_usec + ((to % 1000) * 1000); + if(tv->tv_usec > 1000000) { + tv->tv_sec++; + tv->tv_usec -= 1000000; + } +} + +static void calculate_timeval_strict(struct timeval *tv, MWTIMEOUT to) +{ + tv->tv_sec += (to / 1000); + tv->tv_usec += ((to % 1000) * 1000); if(tv->tv_usec > 1000000) { tv->tv_sec++; tv->tv_usec -= 1000000; __________________________________________________ Do You Yahoo!? Yahoo! Finance - Get real-time stock quotes http://finance.yahoo.com | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Subject:
Re: [nanogui] An average accurate periodic timer
From: "Greg Haerr" ####@####.#### Date: 28 Aug 2002 17:08:36 -0000 Message-Id: <029501c24eb4$198ac5c0$3aba46a6@xmission.com> : What I want from periodic timer is, although each timer event may not : arrives accurately, the average time should be accurate. That is to : say, there should be exactly 40 timer events come from server in 1 : second if the timer period is 25ms. To solve this problem, perhaps the third argument to GrCreateTimer should be the type of timer, not just a boolean for periodic or not. I haven't yet added Alex's GrCreateTimer patch, since it changes the API and will break existing programs. I will be adding it creating a GrCreateTimerEx entry point, with GrCreateTimer #defined to the new *Ex entry point. Comments? Regards, Greg : : To solve this problem, I modify slightly the way to calculate new : timeout value. Instead of base on current time, I calculate it base : on old timeout value. Please see the patch below. : : I believe it is not of gerenal interest. But it is useful to me. : : Regards, : Sheng : : : --- microwin-aph/src/engine/devtimer.c Mon Apr 8 10:30:18 2002 : +++ microwin-aph-new/src/engine/devtimer.c Wed Aug 28 09:34:31 2002 : @@ -65,6 +65,7 @@ : static struct timeval current_time; : : static void calculate_timeval(struct timeval *tv, MWTIMEOUT to); : +static void calculate_timeval_strict(struct timeval *tv, MWTIMEOUT to); : static signed long time_to_expiry(struct timeval *t); : : MWTIMER *GdAddTimer(MWTIMEOUT timeout, MWTIMERCB callback, void *arg, : @@ -159,7 +160,7 @@ : if(time_to_expiry(&t->timeout) <= 0) { : t->callback(t->arg); : if(!t->periodic) GdDestroyTimer(t); : - else calculate_timeval(&t->timeout, t->period); : + else calculate_timeval_strict(&t->timeout, : t->period); : } : t = n; : } : @@ -175,6 +176,16 @@ : { : tv->tv_sec = current_time.tv_sec + (to / 1000); : tv->tv_usec = current_time.tv_usec + ((to % 1000) * 1000); : + if(tv->tv_usec > 1000000) { : + tv->tv_sec++; : + tv->tv_usec -= 1000000; : + } : +} : + : +static void calculate_timeval_strict(struct timeval *tv, MWTIMEOUT to) : +{ : + tv->tv_sec += (to / 1000); : + tv->tv_usec += ((to % 1000) * 1000); : if(tv->tv_usec > 1000000) { : tv->tv_sec++; : tv->tv_usec -= 1000000; : : : __________________________________________________ : Do You Yahoo!? : Yahoo! Finance - Get real-time stock quotes : http://finance.yahoo.com : : --------------------------------------------------------------------- : To unsubscribe, e-mail: ####@####.#### : For additional commands, e-mail: ####@####.#### : | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[<<] [<] Page 1 of 1 [>] [>>] |