From: "Randy.Dunlap" <rddunlap@osdl.org>
To: Henry Margies <henry.margies@gmx.de>
Cc: linux-kernel@vger.kernel.org, george@mvista.com
Subject: Re: Is there a problem in timeval_to_jiffies?
Date: Wed, 15 Sep 2004 20:30:39 -0700 [thread overview]
Message-ID: <20040915203039.369bb866.rddunlap@osdl.org> (raw)
In-Reply-To: <20040912163319.6e55fbe6.henry.margies@gmx.de>
On Sun, 12 Sep 2004 16:33:19 +0200 Henry Margies wrote:
| Hello
|
| Why is nobody answering my question? I tested my application also on
| x86. The result is the same. For me, it looks like there is a problem.
| The only difference is, that my x86 has a TICK value of 1ms and my arm
| device a value of 10ms
|
| Imagine, there are 3 timers.
|
| timer1 is for 1s,
| timer2 is for 0.1s,
| timer3 is for 0.01s.
|
| Now, timer1 should finish after 10 times of timer2 and 100 times of
| timer3. But this is not, because every interval is 1ms (10ms on arm)
| longer than it should be.
|
| (on x86)
| timer1 finishes after 1001ms,
| timer2 after 10*101ms = 1010ms,
| timer3 after 100*11ms = 1100ms
|
| (on arm)
| timer1 finishes after 1010ms,
| timer2 after 10*110ms = 1100ms,
| timer3 after 100*20ms = 2000ms!!!
|
| The output of my test application is the following on x86:
|
| (timer1)
| TIMER_INTERVAL =1000ms
| COUNTER =1
| expected elapsed time =1000ms
| elapsed time =1000ms and 845ns
|
| (timer2)
| TIMER_INTERVAL =100ms
| COUNTER =10
| expected elapsed time =1000ms
| elapsed time =1010ms and 29ns
|
| (timer3)
| TIMER_INTERVAL =10ms
| COUNTER =100
| expected elapsed time =1000ms
| elapsed time =1099ms and 744ns
|
|
| Please have a look into my test application:
|
| void sig_alarm(int i)
| {
| struct timeval tv;
|
| gettimeofday(&tv, NULL);
|
| if (c>=COUNTER) {
| int elapsed;
| c = 0;
| elapsed = (tv.tv_sec-start.tv_sec)*1000000
| + tv.tv_usec-start.tv_usec;
|
| printf( "TIMER_INTERVAL =%dms\n"
| "COUNTER =%d\n"
| "expected elapsed time =%dms\n",
| TIMER_INTERVAL,
| COUNTER,
| TIMER_INTERVAL*COUNTER);
|
| printf("elapsed time =%dms and %dns\n\n\n",
| elapsed/1000, elapsed%1000);
|
| }
|
| if (!c)
| start = tv;
|
| c++;
|
| }
|
| int main()
| {
| struct itimerval itimer;
|
| itimer.it_interval.tv_sec = 0;
| itimer.it_interval.tv_usec= TIMER_INTERVAL*1000;
|
| itimer.it_value.tv_sec = 0;
| itimer.it_value.tv_usec= TIMER_INTERVAL*1000;
|
| signal(SIGALRM, sig_alarm);
|
| setitimer(ITIMER_REAL, &itimer, NULL);
|
| getc(stdin);
|
| return 0;
| }
|
|
| As I wrote, I think the problem is in timeval_to_jiffies. On my arm
| device 10ms are converted to 20ticks. On x86, 10ms are converted to
| 11ticks.
|
| Can somebody agree on that or at least point me to my mistakes?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I agree that timeval_to_jiffies() has some serious rounding errors.
I don't see why it even cares about any of the scaled math in the
(inline) function. I rewrote it (for userspace, not kernelspace)
like so, with expected results:
static __inline__ unsigned long
tv_to_jifs(const struct timeval *value)
{
unsigned long sec = value->tv_sec;
long usec = value->tv_usec;
if (sec >= MAX_SEC_IN_JIFFIES){
sec = MAX_SEC_IN_JIFFIES;
usec = 0;
}
return (((u64)sec * (u64)HZ) +
(((u64)usec + (u64)HZ - 1LL) / (unsigned long)HZ));
}
Results of timeval_to_jiffies() compared to tv_to_jifs() [small sample]:
(tv_sec is fixed at 5, with tv_usec varying)
+--- timeval_to_jiffies()
V v--- tv_to_jifs()
tv_usec: 499000, jifs: 5500, jf2: 5499
tv_usec: 499100, jifs: 5500, jf2: 5500
tv_usec: 499900, jifs: 5501, jf2: 5500
tv_usec: 500000, jifs: 5501, jf2: 5500
tv_usec: 500100, jifs: 5501, jf2: 5501
tv_usec: 500900, jifs: 5502, jf2: 5501
tv_usec: 501000, jifs: 5502, jf2: 5501
tv_usec: 501100, jifs: 5502, jf2: 5502
tv_usec: 501900, jifs: 5503, jf2: 5502
tv_usec: 502000, jifs: 5503, jf2: 5502
tv_usec: 502100, jifs: 5503, jf2: 5503
I think that tv_to_jifs() can be written for kernel use by using
do_div(), but I haven't tried that yet.
--
~Randy
next prev parent reply other threads:[~2004-09-16 3:31 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-09 13:48 Henry Margies
2004-09-12 14:33 ` Henry Margies
2004-09-16 3:30 ` Randy.Dunlap [this message]
2004-09-16 9:54 ` George Anzinger
2004-09-16 15:38 ` Henry Margies
2004-09-16 18:10 ` Henry Margies
[not found] ` <20040916200203.6259e113.henry.margies@gmx.de>
2004-09-16 20:19 ` George Anzinger
2004-09-17 9:55 ` Henry Margies
2004-09-29 20:56 ` Tim Bird
2004-09-29 21:24 ` Jon Masters
2004-10-01 11:42 ` Henry Margies
[not found] <2CxDn-2ib-51@gated-at.bofh.it>
[not found] ` <2DDGs-7Om-31@gated-at.bofh.it>
[not found] ` <2EVhQ-6Qe-5@gated-at.bofh.it>
[not found] ` <2F1e7-2r9-21@gated-at.bofh.it>
[not found] ` <2Fb3o-1cT-27@gated-at.bofh.it>
[not found] ` <2Fb3o-1cT-25@gated-at.bofh.it>
[not found] ` <2FnQM-1wt-1@gated-at.bofh.it>
[not found] ` <2JTS7-5Ri-3@gated-at.bofh.it>
2004-09-29 22:03 ` Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040915203039.369bb866.rddunlap@osdl.org \
--to=rddunlap@osdl.org \
--cc=george@mvista.com \
--cc=henry.margies@gmx.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®