[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