I am using a pentium II.  Even so, that shouldn't account for the large
delay of several microseconds... I think maybe it's just that programming
the timer takes a while...

On Wed, 24 Apr 2002, Norm Dresner wrote:

> 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