You are not logged in.
Pages: 1
Hi,
When using setitimer, the alarm signal comes too early when restarting the timer.
My program has some code (sendloop) executing every 100ms. This is done by executing the sendloop-code on receiving the alarmsignal and calling setitimer on the end of the sendloop.
When some data is received, the sendloop must start earlier (5ms, but changed to 10ms) and not wait 100ms, so the setitimer is stopped and then set to 5ms.
This gives strange behaviour:
1245058533.560818 | SendLoop: loopstate=2, respcount=1
1245058533.560933 | start timer 100000 us @ SendLoop-case1
(10125) setitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
1245058533.573431 | stop timer @ newData
(10125) setitimer: value = 0 s + 0 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 0 us, interval = 0 s + 0 us
1245058533.573667 | start timer 5000 us @ newData
(10125) setitimer: value = 0 s + 5000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 10000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 0 us, interval = 0 s + 0 us
1245058533.574632 | SendLoop: loopstate=2, respcount=2
1245058533.574769 | start timer 100000 us @ SendLoop-case1
(10125) setitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 0 us, interval = 0 s + 0 us
1245058533.674643 | SendLoop: loopstate=2, respcount=2
1245058533.674792 | start timer 100000 us @ SendLoop-case1
(10125) setitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 100000 us, interval = 0 s + 0 us
(10125) getitimer: value = 0 s + 0 us, interval = 0 s + 0 us
1245058533.774598 | SendLoop: loopstate=2, respcount=2
Has someone got any idea what could be wrong here?
Offline
I really can't tell what's going on from just your debugging output there... I have no
context without seeing the code... I don't understand the seemingly double getitimer()
output you have, where the second one retrieves 0.0, nor exactly how long after the
first one that's being done...
Basically, we're going to need more information, and preferably some code...
Offline
This was indeed not very clear...
My kernel version is 2.4.32.
The code that matters is between a lot more code, so I hope some snippets could make the problem clear to you.
Setting the timer:
// set
itv_real = itv;
fprintf(stderr, "(%d) setitimer: value = %d s + %d us, interval = %d s + %d us\n", (int) getpid(), (int) itv.it_value.tv_sec, (int) itv.it_value.tv_usec, (int) itv.it_interval.tv_sec, (int) itv.it_interval.tv_usec);
setitimer(ITIMER_REAL, &itv_real, NULL);
getitimer(ITIMER_REAL, &itv_get);
fprintf(stderr, "(%d) getitimer: value = %d s + %d us, interval = %d s + %d us\n", (int) getpid(), (int) itv_get.it_value.tv_sec, (int) itv_get.it_value.tv_usec, (int) itv_get.it_interval.tv_sec, (int) itv_get.it_interval.tv_usec);
When the alarm signal has arrived:
getitimer(ITIMER_REAL, &itv_get);
fprintf(stderr, "(%d) getitimer: value = %d s + %d us, interval = %d s + %d us\n", (int) getpid(), (int) itv_get.it_value.tv_sec, (int) itv_get.it_value.tv_usec, (int) itv_get.it_interval.tv_sec, (int) itv_get.it_interval.tv_usec);
... and the SendLoop is executed (which will display the time)
What happens:
- timer is started with 100000us @ .560933
- timer is stopped @ .573431
- timer is started with 5000us (actually 10000us) @ .573667
- timer is finished @ .574632
The time between last start and finish is not 10000us, but 965us :confused: .
Please let me know if you need more information.
Offline
beat = current time rounded up to nearest interval value;
loop {
while (beat < current time) {
fire periodic event;
beat += interval;
}
setup select masks for I/O;
timeout = interval;
len = select(len, &readmask, &writemask, &exceptionmask, &timeout);
if (len < 1) {
continue; /* Can wake up from other things so check for periodic events */
}
process I/O according to select masks;
}
Offline
Well, it was about 0.5ms too early at most, and considering the code is using
signals and stuff it's probably not that timing sensitive anyway. Keep in mind
that the clock ticks in 10ms intervals and waiting 10ms too long when the user
asks for a 10ms delay is probably worse than waiting 9.5ms. Heck, the
setitimer() call itself could take forever as far as you know, so it's all very
shady anyway, standard or no standard.
Offline
Thank you all for the great replies.
I applied the "+1" patch you mentioned. Then the delay was not between 0...10ms anymore, but between 10...20ms.
Somewhere I read that the HZ (default set to 100) caused the resolution of 10ms, so I changed HZ to 500 (param.h). Now when I set a timer for 10ms, I get a delay between 10...12ms.
This solution seems better to me, but I am not aware if there are any side-affects that could do harm elsewhere. Do you know if there are?
Offline
Pages: 1