comp.lang.ada
 help / color / mirror / Atom feed
* Using "delay until" in real-time
@ 2000-12-12 16:27 Ted Dennison
  2000-12-12 18:01 ` Mike Silva
                   ` (9 more replies)
  0 siblings, 10 replies; 33+ messages in thread
From: Ted Dennison @ 2000-12-12 16:27 UTC (permalink / raw)


I came across an interesting problem the other day that I'd like to
share, in the hopes that someone here has another solution that the ones
we thought up.

We have a real-time scheduler that uses the "delay until" statement to
perform its scheduling. So far, this shouldn't shock anyone, as
real-time scheduling is supposedly what "delay until" was put in the
language for.

Our scheduling code looks something like this (very simplified, and not
compiled. My apologies ahead of time if Deja screws up the formatting):

---
Iteration_Hz : constant Float := 60.0;

task Executive is
   Iteration : constant Ada.Real_Time.Time_Span
      := Ada.Real_Time.To_Time_Span (Duration(1.0/Iteration_Hz));

   Next_Time : Ada.Real_Time.Time := Ada.Real_Time.Clock + Iteration;
begin
   loop
      -- Perform scheduling tasks
      ...

      Next_Time := Next_Time + Iteration;
      delay until Next_Time;
   end loop;
end Executive;

---

That looks pretty straightforward, right? Well, unfortunately, its *WRONG*.

1/60 works out to about 0.016(6-repeating). That can't be accurately
represented in an IEEE floating-point register. So what we get is
something like 0.016667 (forgive me if I'm rounding the wrong digit).
That rouding error slowly accumulates over time, until after about 52
seconds our poor Executive task skips a tick. On our system ticks come
at 240Hz, so that means that once every 52 seconds the executive
scheduler waits about 20ms instead of 16.6(6-repeating)ms. Of course
this wreaks havoc in our hard-realtime system.

So the question is, what's the best way to solve this problem? Here's
what we came up with so far:

  o  Use the RTOS' "taskDelay" function to delay the appropriate amount
of ticks (4).

I don't like this one, as its a non-Ada solution, and thus renders our
scheduler non-portable. Its also succeptable to drift if something
causes an extra tick to pass before we get to the taskDelay.

  o  Check the Ada.Real_Time.Clock every cycle when we awaken, and add
the Iteration to that for the "delay until".

I don't like this because the clock check is going to be fairly
expensive, and this solution is also succeptable to drift.

  o  Figure out what the denominator is (60 in this case), and redo the
calculation every time that number of runs have happened.

For instance, in the above code, I'd add something like:
      Runs := Runs + 1;
      if Runs >= Natural(Iteration_Hz) then
         -- Adjust for drift due to rounding errors.
         Runs := 0;
         Run_Time := Run_Time + Ada.Real_Time.To_Time_Span (1.0);
         Next_Time := Run_Time;
      else
         Next_Time := Next_Time + Iteration;
      end if;

I kind of like this option, as it is a mathematical solution to what is,
in essence, a mathematical problem. This ought to work as long as the
denominator can be counted on to be a whole (natural) number. In my
case, I think it can.

Since this problem should happen to anyone using "delay until" with an
iteration rate divisible by 3, and 60, 30, and 15Hz are common rates in
the industry, I can't be the first person to stumble on this problem.
How does everyone else handle it?


--
T.E.D.

http://www.telepath.com/~dennison/Ted/TED.html


Sent via Deja.com
http://www.deja.com/



^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2000-12-21  0:08 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-12-12 16:27 Using "delay until" in real-time Ted Dennison
2000-12-12 18:01 ` Mike Silva
2000-12-12 19:57   ` Ted Dennison
2000-12-12 23:02     ` Mike Silva
2000-12-12 23:49       ` Ted Dennison
2000-12-18  6:26     ` Ray Blaak
2000-12-12 20:00 ` Ken Garlington
2000-12-12 20:40   ` Ted Dennison
2000-12-13  4:02     ` Ken Garlington
2000-12-13 14:29       ` Ted Dennison
2000-12-13 16:53     ` Larry Hazel
2000-12-13 17:41       ` Ted Dennison
2000-12-12 20:22 ` Keith Thompson
2000-12-12 20:54   ` Ted Dennison
2000-12-13  5:35   ` tmoran
2000-12-12 20:23 ` David C. Hoos, Sr.
2000-12-12 21:58   ` Ted Dennison
2000-12-12 23:18   ` Jeff Carter
2000-12-12 21:18 ` JP Thornley
2000-12-12 22:31   ` Ted Dennison
2000-12-13  8:02     ` Brian Orpin
2000-12-13 17:32     ` JP Thornley
2000-12-12 23:09 ` Ted Dennison
2000-12-13  7:43 ` Brian Orpin
2000-12-15  0:27 ` Frank
2000-12-19  7:50 ` Martin Gangkofer
2000-12-20  3:32   ` Ted Dennison
2000-12-20  5:29     ` tmoran
2000-12-20  7:59     ` Martin Gangkofer
2000-12-20  9:15       ` java servlets JF Harrison
2000-12-20 12:50     ` Using "delay until" in real-time Marin David Condic
2000-12-21  0:08     ` Alejandro R. Mosteo
2000-12-20  3:17 ` Ted Dennison

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox