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/

Reply via email to