This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]