This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: periodic threads with kapi?
Bart Veer <bartv@ecoscentric.com> writes:
> >>>>> "Ryan" == Ryan Boder <icanoop@bitwiser.org> writes:
>
> Ryan> On Sun, Aug 17, 2003 at 07:43:16PM +0100, Bart Veer wrote:
> >> >>>>> "Ryan" == Ryan Boder <icanoop@bitwiser.org> writes:
> >>
> Ryan> Is there a clean way to do periodic threads with absolute
> Ryan> timing, as opposed to the relative timing you get with
> Ryan> cyg_thread_delay()?
> >>
> >> This should be easy enough using something like:
> >>
> >> void
> >> my_thread_delay_absolute(cyg_tick_count_t abs_time)
> >> {
> >> cyg_tick_count_t delay = abs_time - cyg_current_time();
> >> if (delay > 0) {
> >> cyg_thread_delay(delay);
> >> }
> >> }
> >>
> >> There is a possible problem if the current thread gets descheduled
> >> between the cyg_current_time() and cyg_thread_delay() calls, causing
> >> the thread to get delayed for longer than intended. You could avoid
> >> that by e.g. temporarily boosting the current thread's priority.
>
> Ryan> The problem still exists doing it that way. In fact that
> Ryan> would even make it worse.
>
> Ryan> The point is that I don't want to read the current time each
> Ryan> period in my thread. That causes drift.
>
> There is no drift. The calling code should calculate the new value of
> abs_time by adding the appropriate number of ticks to the previous
> value of abs_time, thus moving from one absolute time to the next. For
> example adding 100 each time will give absolute intervals of 1 second
> (assuming the usual 10ms clock).
>
> If instead the calling code calculated the new value of abs_time by
> adding 100 to cyg_current_time() rather than to the previous value of
> abs_time then you would get drift - that would be equivalent to
> calling cyg_thread_delay().
This might not drift, but it will jitter. A simple fix to the
given routine would be to lock the scheduler:
void
my_thread_delay_absolute(cyg_tick_count_t abs_time)
{
cyg_scheduler_lock();
cyg_tick_count_t delay = abs_time - cyg_current_time();
if (delay > 0) {
cyg_thread_delay(delay);
}
cyg_scheduler_unlock();
}
If the OP wants genuine periodic threads then it is probably best to
set up an interval alarm that posts to a semaphore each time it
triggers. This would be much cheaper in terms of overhead than using
cyg_thread_delay(). It also allows the alarm function to detect
whether the periodic thread has overrun.
--
Nick Garnett eCos Kernel Architect
http://www.ecoscentric.com The eCos and RedBoot experts
--
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss