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