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/