Another thought:  What CPU & motherboard are you using and what's happening
with the CPU's cache at each call;  IIRC some 486 systems actually did a
cache flush after each jump/call (possibly conditioned by the distance of
the relocation).  Is there anything funny with the cache -- like flushing
and rebuilding it taking place.

    Norm

----- Original Message -----
From: Calin A. Culianu <[EMAIL PROTECTED]>
To: Norm Dresner <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Sent: Wednesday, April 24, 2002 6:23 PM
Subject: Re: [rtl] Does nanosleep() oversleep?


>
> Hehe, well thanks Norm for looking at the code... no need to mess with
> this yourself unless you are of course curious about this quirk.
>
> You are in principle, correct.
>
> However, that rtl_printf() doesn't get factored into anything that
affects
> the calculation of how long nanosleep slept, and the other simple
> computations, including gethrtime() each take only on the order of 50-128
> nanosecond on my machine.  All of this doesn't account for the tens of
> thousands of lost nanoseconds after *each* call to nanosleep().  My
> suspicion is that nanosleep oversleeps due to inherent latency in
> programming the motherboard's timer each time.  A better solution, I
know,
> is to use periodic threads, which program the timer only once (I
think..).
>
> I tried what you suggested, just as a proof of concept.
>
> After sleeping for hundreds of thousands of times, without any extraneous
> code aside from sleeping and computing the next wakeup time (all of which
> should take on the order of hundreds of nanos _tops_), nanosleep still
> seems to oversleep on the order of TENS OF THOUSANDS of nanos, per call.
> (I verified this by adding up the time slept and then later outputting it
> to a printk()  on module termination.. and yes, I did get around the
> inability to printk long longs in the kernel by doing some hacking..).
>
>
> Still no go.  I am going to avoid nanosleep() at all costs due to its
> consistent overleeping.  Instead, I will always use periodic tasks, which
> don't seem to suffer from this problem (as severely).
>
> -Calin
>
>  On Wed, 24 Apr 2002, Norm
> Dresner wrote:
>
> > >From a very brief inspection, I see that the loop contains, in
addition to
> > the nanosleep invocation,  several calls to gethrtime() and one
> > printf_rtl(), all of which contribute to the loop's period.  I think a
> > better test would be to have a very simple loop toggling a bit on an
output
> > port and observing the results on a 'scope or a frequency meter.
> >
> >     Norm
> >
> > (As soon as the rush is over, I'd love to take some time and play with
> > this.  Maybe July at my current loading.)
> >
> > ----- Original Message -----
> > From: Calin A. Culianu <[EMAIL PROTECTED]>
> > To: <[EMAIL PROTECTED]>
> > Sent: Wednesday, April 24, 2002 4:24 PM
> > Subject: [rtl] Does nanosleep() oversleep?
> >
> >
> > >
> > >
> > > What's wrong with this code?  Why does nanosleep() *always* oversleep
by
> > > not a few nanosecond.. but by like 15 microseconds on a PII-400, per
> > > iteration?
> > >
> > >
> > > /*
> > >  * Copyright (C) 2002 Calin Culianu
> > >  *
> > >  * This program is free software; you can redistribute it and/or
> > >  * modify it under the terms of the GNU General Public License
> > >  * as published by the Free Software Foundation; either version 2
> > >  * of the License, or (at your option) any later version.
> > >  *
> > >  * This program is distributed in the hope that it will be useful,
> > >  * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > >  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > >  * GNU General Public License for more details.
> > >  *
> > >  * You should have received a copy of the GNU General Public License
> > >  * along with this program (see COPYRIGHT file); if not, write to the
> > >  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> > >  * Boston, MA 02111-1307, USA, or go to their website at
> > >  * http://www.gnu.org.
> > >  */
> > >
> > >
> > > #include <linux/module.h>
> > > #include <linux/kernel.h>
> > > #include <linux/version.h>
> > > #include <linux/types.h>
> > > #include <linux/errno.h>
> > >
> > > #include <rtl.h>
> > > #include <rtl_sched.h>
> > >
> > > #define MYNAME "nanotest"
> > >
> > > static void *rt_task (void *arg);
> > >
> > > static const int n_sleeps = 660;
> > > static const hrtime_t ns_bet_sleeps = 1000000;
> > >
> > > static pthread_t task = 0;          /* main RT task */
> > >
> > > int init_module(void)
> > > {
> > >   pthread_attr_t attr;
> > >   struct sched_param sched_param;
> > >
> > >   /* create the realtime task */
> > >   pthread_attr_init(&attr);
> > >   pthread_attr_setfp_np(&attr, 1);
> > >   sched_param.sched_priority = 1;
> > >   pthread_attr_setschedparam(&attr, &sched_param);
> > >   if ( pthread_create(&task, &attr, rt_task, (void *)0) ) {
> > >     return -1;
> > >   }
> > >
> > >   return 0;
> > >
> > > }
> > >
> > > void cleanup_module(void)
> > > {
> > >   /* delete daq_task */
> > >   if (task) {
> > >     if (!pthread_delete_np(task))
> > >       printk (MYNAME ": deleted RT task\n");
> > >     else
> > >       printk (MYNAME ": cannot find RT task (it died?).\n");
> > >   }
> > > }
> > >
> > > /* dummy rt loop to test nanosleep and how much it oversleeps */
> > > static void *rt_task (void *arg)
> > > {
> > >   int n_loops = 0, diff = 0, one_call_to_gethrtime;
> > >   hrtime_t projected_wakeup_time = 0, loopstart, nanos_to_sleep, tmp;
> > >
> > >   tmp = gethrtime();
> > >   one_call_to_gethrtime = gethrtime() - tmp;
> > >
> > >   rtl_printf(MYNAME ": one call to gethrtime() takes %d ns\n",
> > >              one_call_to_gethrtime);
> > >
> > >   do {
> > >
> > >     loopstart = gethrtime();
> > >
> > >     if (projected_wakeup_time) /* skips first iteration */
> > >       diff += loopstart - projected_wakeup_time;
> > >
> > >     if ( (++n_loops) % n_sleeps == 0) {
> > >       rtl_printf(MYNAME ": cum difference after %d iterations is
%d\n",
> > >                  n_sleeps, diff);
> > >       diff = 0;
> > >     }
> > >
> > >     nanos_to_sleep = ns_bet_sleeps - (gethrtime() - loopstart);
> > >     projected_wakeup_time = gethrtime() + nanos_to_sleep;
> > >
> > >   } while ( !nanosleep (hrt2ts(nanos_to_sleep), NULL) );
> > >
> > >   return (void *)0;
> > > }
> > >
> > >
> > > -- [rtl] ---
> > > To unsubscribe:
> > > echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> > > echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> > > --
> > > For more information on Real-Time Linux see:
> > > http://www.rtlinux.org/
> > >
> >
>

-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
--
For more information on Real-Time Linux see:
http://www.rtlinux.org/

Reply via email to