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/