diff -Nur latencytest.0.5.5_orig/README latencytest.0.5.5/README --- latencytest.0.5.5_orig/README 2004-09-13 17:50:50.000000000 +0100 +++ latencytest.0.5.5/README 2005-03-30 06:23:27.000000000 +0100 @@ -15,6 +15,8 @@ 2. make binaries cd src + On non-i386 machines edit Makefile to uncomment one of the CFLAG + settings. make make install diff -Nur latencytest.0.5.5_orig/kernel/latencytest.c latencytest.0.5.5/kernel/latencytest.c --- latencytest.0.5.5_orig/kernel/latencytest.c 2004-07-16 14:18:26.000000000 +0100 +++ latencytest.0.5.5/kernel/latencytest.c 2005-03-30 05:56:28.000000000 +0100 @@ -1,7 +1,6 @@ /* * invoking periodical RTC interrupts and report the stack pointers * - * for i386 only! */ #include @@ -89,10 +88,10 @@ } memcpy(&irq_info.comm[pcnt][0], current->comm, 16); } -#elif defined(__ppc__) +#elif defined(__powerpc__) static inline void copy_stack(int pcnt) { - unsigned long sp, stack_top, prev_sp, ret; + unsigned long sp, stack_top, prev_sp; int i; unsigned long *dump = &irq_info.stacks[pcnt][0]; unsigned short idx; @@ -130,8 +129,10 @@ spin_lock(&my_lock); count++; - if (count < irq_count) + if (count < irq_count) { + spin_unlock(&my_lock); return; + } count = 0; pcnt = irq_info.processed; irq_info.processed++; @@ -144,9 +145,13 @@ static int my_start(void) { + int rc; + if (irq_count) { - rtc_control(&rtc_task, RTC_IRQP_SET, rtc_freq); - rtc_control(&rtc_task, RTC_PIE_ON, 0); + rc = rtc_control(&rtc_task, RTC_IRQP_SET, rtc_freq); + if (rc != 0) return rc; + rc = rtc_control(&rtc_task, RTC_PIE_ON, 0); + if (rc != 0) return rc; rtc_running = 1; return 0; } diff -Nur latencytest.0.5.5_orig/src/Makefile latencytest.0.5.5/src/Makefile --- latencytest.0.5.5_orig/src/Makefile 2004-02-15 20:42:25.000000000 +0000 +++ latencytest.0.5.5/src/Makefile 2005-03-30 06:20:57.000000000 +0100 @@ -3,6 +3,9 @@ all: $(TARGETS) CFLAGS += -Wall +# For PPC uncomment one of the following lines. +#CFLAGS += -DUSE_PPC_VEA_TIMEBASE +#CFLAGS += -DUSE_GENERIC_TIMER measure: measure.o gfx.o $(CC) $(CFLAGS) -o $@ measure.o gfx.o -lm -lgd diff -Nur latencytest.0.5.5_orig/src/measure.c latencytest.0.5.5/src/measure.c --- latencytest.0.5.5_orig/src/measure.c 2004-07-12 11:45:40.000000000 +0100 +++ latencytest.0.5.5/src/measure.c 2005-03-30 05:59:01.000000000 +0100 @@ -37,6 +37,25 @@ static inline unsigned long long int rdtsc(void) { +#ifdef USE_GENERIC_TIMER + static struct timeval mytv; + static struct timezone tz; + gettimeofday(&mytv,&tz); + return(mytv.tv_sec*1000000+mytv.tv_usec); +#elif USE_PPC_VEA_TIMEBASE + unsigned long x, y, z; + + __asm __volatile ( "1:\n" + " mftbu %0\n" + " mftb %1\n" + " mftbu %2\n" + " cmpw %0,%2\n" + " bne 1b\n" + " mftb %1\n" + : "=r" (x), "=r" (y), "=r" (z) + : ); + return ((((unsigned long long int) z)<<32) | y) ; +#else unsigned long long int x, y; for (;;) { __asm__ volatile ("rdtsc" : "=A" (x)); @@ -44,8 +63,28 @@ if (y - x < 1000) return y; } +#endif } +#if USE_PPC_VEA_TIMEBASE +static double tb_ticks_per_sec = 0.0; + +static inline void calibrate_tb(void) +{ + struct timeval tv1, tv2 ; + unsigned long long int tb1, tb2 ; + double t1, t2 ; + gettimeofday(&tv1, NULL) ; + tb1 = rdtsc() ; + sleep(5) ; + gettimeofday(&tv2, NULL) ; + tb2 = rdtsc() ; + t1 = tv1.tv_sec + tv1.tv_usec/1000000.0 ; + t2 = tv2.tv_sec + tv2.tv_usec/1000000.0 ; + tb_ticks_per_sec = (tb2-tb1)/(t2-t1) ; +} +#endif + static unsigned long long time_offset; #define mygettime() (rdtsc() - time_offset) @@ -56,7 +95,13 @@ inline static double wallclock(unsigned long long sc) { +#ifdef USE_GENERIC_TIMER + return (double)sc / 1000000.0; +#elif USE_PPC_VEA_TIMEBASE + return (double)sc / tb_ticks_per_sec; +#else return (double)sc / cpu_hz; +#endif } static int init_test(const char *device_file, int freq, int count, int use_rtc); @@ -118,6 +163,9 @@ time_offset = rdtsc(); /* initialization */ +#if USE_PPC_VEA_TIMEBASE + calibrate_tb(); +#endif use_rtc = 0; frequency = 1024; @@ -130,6 +178,7 @@ switch (c) { case 'I': use_rtc = 1; + wakeup_count = 1; break; case 'c': cpu_load = atof(optarg); @@ -223,7 +272,11 @@ stinfo.start_time = wallclock(start_sc); fprintf(stderr, "start time = %g\n", stinfo.start_time); - start_trigger(use_rtc); + err = start_trigger(use_rtc); + if (err < 0) { + fprintf(stderr, "fatal ioctl error %d\n", -err); + exit(1); + } for (;;) { int nrun = stinfo.num_runs; unsigned long long time_head, time_cpu, time_sync; @@ -347,7 +400,8 @@ } else { devfd = open(device_file, O_RDWR); if (devfd < 0) { - fprintf(stderr, "error opening device\n"); + fprintf(stderr, "error opening test device\n"); + perror("open"); return -errno; } @@ -367,7 +421,7 @@ inline static int start_trigger(int use_rtc) { if (use_rtc) - return ioctl(devfd, RTC_PIE_ON); + return ioctl(devfd, RTC_PIE_ON, 0); else return ioctl(devfd, LAT_TEST_START, 0); } @@ -416,11 +470,15 @@ struct pollfd pfd; unsigned long t; pfd.fd = devfd; - pfd.fd = POLLIN; - if (poll(&pfd, 1, -1) < 0) + pfd.events = POLLIN; + if (poll(&pfd, 1, -1) < 0) { + perror("poll"); return -errno; - if (read(devfd, &t, sizeof(t)) < 0) + } + if (read(devfd, &t, sizeof(t)) < 0) { + perror("read"); return -errno; + } } else { if (ioctl(devfd, LAT_TEST_READ, info) < 0) return -errno; @@ -492,6 +550,14 @@ cpu_hz=atof(&s1[10])*1000000.0; break; } + if(!memcmp(s1,"clock",5)) + { + char *colon; + colon = index(s1,':'); + if( colon == NULL ) break; + sscanf(colon+1,"%lf",&cpu_hz); + cpu_hz *= 1000000.0; + } } fclose(f); if(cpu_hz < 1.0) { diff -Nur latencytest.0.5.5_orig/src/showtrace.c latencytest.0.5.5/src/showtrace.c --- latencytest.0.5.5_orig/src/showtrace.c 2004-07-16 14:20:36.000000000 +0100 +++ latencytest.0.5.5/src/showtrace.c 2004-10-19 19:12:52.000000000 +0100 @@ -165,7 +165,7 @@ float threshold = 0; static char *ksymfile = "/proc/kallsyms"; - while ((c = getopt(argc, argv, "k:hpr:)) != -1) { + while ((c = getopt(argc, argv, "k:hpr:")) != -1) { switch (c) { case 'k': ksymfile = optarg;