[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-rt
Subject: Re: [Rtl] Re: time is running out
From: Theo Veenker <Theo.Veenker () let ! uu ! nl>
Date: 2005-02-14 14:36:39
Message-ID: 4210B777.9040002 () let ! uu ! nl
[Download RAW message or body]
Der Herr Hofrat wrote:
>>>did you check with the latest CVS changes ?
>>>I had CLOCK_GPOS running - but I don't see that
>>>behavior any longer with the changes (recompiling
>>>the kernel and rtlinux)
>>>
>>>hofrat
>>
>>I will try after getting the CVS changes. Might take a few days I'm afraid,
>>rather busy with more boring stuff. I'll let you know the result.
>>
>
> I think I have the problem located. It happens on all AMD CPUs when
> configured as generic 686 because the CLOCK_TICK_RATE for the AMD boxes
> seems to be 1189200 instead of 1193100 - so after "correcting" the tick
> rate in linux/include/asm-i386/timex.h (at the top of the file) - the
> problem is resolved and your test code schows the expeced 0 +/- 32 (on
> an idle system - under load the +/- will off course increase).
>
> pleas cross check on your system if this solves it for you - if it does
> not I would need detailed specs from the system (checked here on three
> different AMD archs (ELAN SC520, AMD Duron , AMD XP)).
I read in linux/include/asm-i386/timex.h
#ifdef CONFIG_MELAN
# define CLOCK_TICK_RATE 1189200 /* AMD Elan has different frequency! */
#else
# define CLOCK_TICK_RATE 1193180 /* Underlying HZ */
#endif
You've changed the latter setting to 1189200 also?
/proc/cpuinfo tells me:
vendor_id : GenuineIntel
cpu family : 15
model : 1
model name : Intel(R) Celeron(R) CPU 1.80GHz
stepping : 3
and in linux/include/linux/autoconf.h I have in the processor type
and features section:
#define CONFIG_MPENTIUMIII 1
Which means in my case CLOCK_TICK_RATE is set to 1193180.
Since on my boxes CLOCK_GPOS runs 151us/s faster than CLOCK_REALTIME
the period of CLOCK_GPOS is (1s-151us)/1s times the period of
CLOCK_REALTIME: 1193180 * (1s-151us)/1s = 1193000.
So I corrected the 1193180 value to 1193000 and recompiled (left the
HZ parameter at 1000 for now). And now I also get +/-32 ns (in idle
situation).
Apparently the definition of CLOCK_TICK_RATE can't be trusted. The
real value is board specific.
What I don't understand is why is the exact value of CLOCK_TICK_RATE
important under RTLinux and apparently not under plain Linux. What
is the difference in keeping wall clock time under Linux and RTLinux?
Theo
P.S.
I have modified the test module to also print the 'corrected'
CLOCK_TICK_RATE value. See attachment.
["clktst.c" (text/x-csrc)]
/*
* clktst.c
*
* Gets CLOCK_REALTIME and CLOCK_GPOS once every second and prints
* the difference between the offsets between the two clock values.
* If the clocks run at the same pace this difference should be zero
* on average.
*
* Also printed is value of CLOCK_TICK_RATE corrected using the
* detected speed difference of CLOCK_REALTIME and CLOCK_GPOS. Of
* course this only makes sence if the actual measurement interval is
* correct.
*
*/
#include <rtl.h>
#include <posix/time.h>
#include <pthread.h>
static pthread_t mythread;
#define INTERVAL 1000000000
static void* testTask(void* arg)
{
hrtime_t realtime, gpostime;
hrtime_t offset, prevoffset;
hrtime_t diff, tickrate;
struct timespec rtres;
struct timespec gpres;
int n;
pthread_make_periodic_np(pthread_self(),
clock_gethrtime(CLOCK_RTL_SCHED), INTERVAL);
clock_getres(CLOCK_REALTIME, &rtres);
clock_getres(CLOCK_GPOS, &gpres);
rtl_printf("rt resolution: %ld ns\n", (long)rtres.tv_nsec);
rtl_printf("gp resolution: %ld ns\n", (long)gpres.tv_nsec);
realtime = clock_gethrtime(CLOCK_REALTIME);
gpostime = clock_gethrtime(CLOCK_GPOS);
prevoffset = offset = gpostime - realtime;
diff = 0;
for (n = 0; ; n++) {
pthread_wait_np();
realtime = clock_gethrtime(CLOCK_REALTIME);
gpostime = clock_gethrtime(CLOCK_GPOS);
offset = gpostime - realtime;
diff = offset - prevoffset;
prevoffset = offset;
tickrate = ((INTERVAL - diff) * CLOCK_TICK_RATE) / INTERVAL;
rtl_printf("%d: %lld %lld\n", n, diff, tickrate);
}
return 0;
}
int init_module(void)
{
pthread_create(&mythread, NULL, testTask, NULL);
return 0;
}
void cleanup_module(void)
{
pthread_cancel(mythread);
pthread_join(mythread, NULL);
}
_______________________________________________
Rtl mailing list
Rtl@rtlinux.org
http://www2.fsmlabs.com/mailman/listinfo/rtl
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic