Hi !

 Since I have reproduced the jitter measurement with identical results on 
 four i486 platforms in the meanwhile running 30min , I guess its worth
 checking if there realy is a problem or if this is a sideeffect of something
 I am doing/running here with my boxes. I don't know if there realy is such
 a delay or if this delay is only "measured" in any case this would be a 
 problem.

 the code is ugly , but it works for me , I now put the cals in a loop wich
 makes the measured execution time a littl higher , but it did not change
 the results.

 the rt_process.c file is thought as replacement of the
 examples/measurement/rt_process.c , it uses the rtl.mk
 file that is located in that directory to find your 
 rtl stuff. modifications are in common.h/monitor.c/Makfile
 and rt_process.c. 

 I would be especialy interested in results from i486 platforms.

 to get the results I did the folowing:

diddl: > cat /proc/interrupts > intr ; ./monitro > jitt ; cat /proc/interrupt >> intr

so I get the interrup count for the interrupts that occured during the test and
the "jitter" in two files. to sort things out I simply do 

diddl: > grep "run1" jitt | cut -f 3 -d ":" | sort | uniq --count

this gives you the "histogram" of jitter events for the run1 (delay between
first and second cal) . 

thx
nmg

default: all

include rtl.mk

histplot: histplot.c
        $(CC) -o histplot histplot.c

monitor: monitor.c
        $(CC) ${INCLUDE} -Wall -O2 -o monitor monitor.c

rt_process.o: rt_process.c
        $(CC) ${INCLUDE} ${CFLAGS} -c rt_process.c -o rt_process.o

all: monitor histplot rt_process.o

#test, remove any modules, load new ones and run app
test: all
        @echo "This tests scheduling accuracy"
        @echo "by running a single periodic task using the one"
        @echo "shot schedular and testing checking times when it is called"
        @echo "First we remove any existing rtl-modules"
        @echo "You may see error warnings from \"make\" - ignore them"
        @echo "Type <return> to continue"
        @read junk
        -rmmod hello
        -rmmod sound
        -rmmod rt_process
        -rmmod frank_module
        (cd ../../; ./rmrtl)
        @echo "Now insert the fifo and scheduler"
        @echo "Type <return> to continue"
        @read junk
        (cd ../../; ./insrtl)
        @echo "Now start the real-time tasks  module"
        @echo "Type <return> to continue"
        @read junk
        @insmod rt_process.o
        @echo "Now starting the application"
        @echo "The \"min\" is the smallest timing error"
        @echo "A negative value means that the task ran too early"
        @echo "The \"max\" is the largest timing error"
        @./monitor

stop_test:
        -rmmod rt_process
        -rmmod rtl_fifo
        -rmmod rtl_sched
        -rmmod rtl_time

clean:
        rm -f *.o monitor  histplot
/*
 * RTL scheduling accuracy measuring example
 *
 * (C) Michael Barabanov, 1997
 *  (C) FSMLabs  1999. [EMAIL PROTECTED]
 *  Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 *  Any use of this code must include this notice.
 */

#include <rtl.h>
#include <rtl_fifo.h>
#include <time.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <pthread.h>
#include <unistd.h>
#include <rtl_debug.h>
#include <errno.h>
#include "common.h"

int ntests=500;
int period=1000000;
int mode=0;
int fifo_size=4000;
int advance=0;

MODULE_PARM(period,"i");
MODULE_PARM(ntests,"i");
MODULE_PARM(mode,"i");
MODULE_PARM(advance,"i");

pthread_t thread;
int fd_fifo;


void *thread_code(void *param) {

        int jittvec_idx;
        hrtime_t expected;
        hrtime_t diff[VECSIZE];
        hrtime_t end[VECSIZE+1];
        hrtime_t min_diff[VECSIZE];
        hrtime_t max_diff[VECSIZE];
        struct sample samp;
        int i;
        int cnt = 0;
        DECLARE_CPUID(cpu_id);

        rtl_printf ("Measurement task starts on CPU %d\n", cpu_id);
        if (mode) {
                int ret = rtl_setclockmode (rtl_getschedclock(), 
RTL_CLOCK_MODE_PERIODIC, period);

                if (ret != 0) {
                        conpr("Setting periodic mode failed\n");
                        mode = 0;
                }
        }

        if (mode) {
                struct timespec resolution;

                /* need to round up the period; should this be done
                 * in pthread_make_periodic? */
                clock_getres (rtl_getschedclock(), &resolution);
                period = timespec_to_ns (&resolution);
        } else {

                rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_ONESHOT, 0);
        }

        expected = clock_gethrtime(rtl_getschedclock()) + 2 * period;

        if (advance) {
                pthread_make_periodic_np (pthread_self(), expected - advance, period);
        } else {
                pthread_make_periodic_np (pthread_self(), expected, period);
        }


        fd_fifo = open("/dev/rtf0", O_NONBLOCK);
        if (fd_fifo < 0) {
                rtl_printf("/dev/rtf0 open returned %d\n", fd_fifo);
                return (void *) -1;
        }

        if (advance) {
                rtl_stop_interrupts(); /* Be careful with this! The task won't be 
preempted by anything else. This is probably only appropriate for small high-priority 
tasks. */
        }

        do {
                for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){
                min_diff[jittvec_idx] = 2000000000;
                max_diff[jittvec_idx] = -2000000000;
                }
                for (i = 0; i < ntests; i++) {
                        ++cnt;
                        pthread_wait_np();
                        for(jittvec_idx=0;jittvec_idx<=VECSIZE;jittvec_idx++){
                                end[jittvec_idx] = clock_gethrtime(CLOCK_UST);
                                }
                        for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){
                                diff[jittvec_idx] = 
end[jittvec_idx+1]-end[jittvec_idx];
                                }
                        for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){
                        if (diff[jittvec_idx] < min_diff[jittvec_idx]) {
                                min_diff[jittvec_idx] = diff[jittvec_idx];
                        }
                        if (diff[jittvec_idx] > max_diff[jittvec_idx]) {
                                max_diff[jittvec_idx] = diff[jittvec_idx];
                        }
                }
                }

                for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){
                        samp.run[jittvec_idx] = min_diff[jittvec_idx];
                        samp.jitt[jittvec_idx] = 
(max_diff[jittvec_idx]-min_diff[jittvec_idx]);
                }
                write (fd_fifo, &samp, sizeof(samp));
        } while (1);
        return 0;
}



int init_module(void)
{
        pthread_attr_t attr;
        struct sched_param sched_param;
        int thread_status;
        int fifo_status;

        rtf_destroy(0);
        fifo_status = rtf_create(0, fifo_size);
        if (fifo_status) {
                rtl_printf("RTL measurement test fail. fifo_status=%d\n",fifo_status);
                return -1;
        }


        rtl_printf("RTL measurement module on CPU %d\n",rtl_getcpuid());
        pthread_attr_init (&attr);
        pthread_attr_setcpu_np(&attr, 0 /*!rtl_getcpuid()*/);
        sched_param.sched_priority = 1;
        pthread_attr_setschedparam (&attr, &sched_param);
        rtl_printf("About to thread create\n");
        thread_status = pthread_create (&thread,  &attr, thread_code, (void *)1);
        if (thread_status != 0) {
                rtl_printf("failed to create RT-thread; errno=\n", errno);
                return -1;
        } else {
/*              rtl_printf("created RT-thread\n"); */
        }

        return 0;
}


void cleanup_module(void)
{
        rtl_printf ("Removing module on CPU %d\n", rtl_getcpuid());
        pthread_delete_np (thread);
        close(fd_fifo);
/* should be:   pthread_cancel(thread); pthread_join(thread); */
/* or:          rtl_pthread_kill_other_threads(); */
        rtf_destroy(0);
}

/*
 * RTL scheduling accuracy measuring example, user program
 *
 * (C) Michael Barabanov, 1997
 *  (C) FSMLabs  1999. [EMAIL PROTECTED]
 *  Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 *  Any use of this code must include this notice.
 */

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <rtl_fifo.h>
#include "common.h"



int main()
{
        int fd0;
        int n;
        int jittvec_idx;
        struct sample samp;
        
        if ((fd0 = open("/dev/rtf0", O_RDONLY)) < 0) {
                fprintf(stderr, "Error opening /dev/rtf0\n");
                exit(1);
        }


        while (1) {

                n = read(fd0, &samp, sizeof(samp));
                for(jittvec_idx=0;jittvec_idx<VECSIZE;jittvec_idx++){
                        printf("run%d:\t %8d, jitt: %8d\n",jittvec_idx,(int) 
samp.run[jittvec_idx], (int) samp.jitt[jittvec_idx]);
                }  
                fflush(stdout);
        }

        return 0;
}

#define LPT_PORT 0x378
#define LPT_IRQ 7
#define RTC_IRQ 8
#define VECSIZE 20

#include <rtl_time.h>


struct sample {
        hrtime_t run[VECSIZE];
        hrtime_t jitt[VECSIZE];
};

Reply via email to