>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/