Branch: Tag:

2001-02-05

2001-02-05 11:24:16 by Mirar (Pontus Hagland) <pike@sort.mirar.org>

better calibration of RDTSC hrtime routine, and a testsuite test

Rev: src/configure.in:1.473
Rev: src/port.c:1.38
Rev: src/testsuite.in:1.382

1: - AC_REVISION("$Id: configure.in,v 1.472 2001/02/03 03:43:35 hubbe Exp $") + AC_REVISION("$Id: configure.in,v 1.473 2001/02/05 11:24:15 mirar Exp $")   AC_INIT(interpret.c)   AC_CONFIG_HEADER(machine.h)   
2695:    AC_CACHE_VAL(pike_cv_own_gethrtime_rdtsc, [    AC_TRY_RUN([   #include <unistd.h> + #include <stdio.h>   #include <sys/time.h>      static long long hrtime_rtsc_zero; -  + static long long hrtime_rtsc_last; + static long long hrtime_max;   static struct timeval hrtime_timeval_zero;   static long double hrtime_conv=0.0;    -  + #define GETTIMEOFDAY(PTR) gettimeofday(PTR,NULL) +    #define RTSC(x) \    __asm__ __volatile__ ( "rdtsc" \    :"=a" (((unsigned long*)&x)[0]), \
2708:      void own_gethrtime_init()   { +  GETTIMEOFDAY(&hrtime_timeval_zero);    RTSC(hrtime_rtsc_zero); -  gettimeofday(&hrtime_timeval_zero,NULL); +  hrtime_rtsc_last=hrtime_rtsc_zero; +  hrtime_max=0;   }    - void own_gethrtime_update(struct timeval *ptr) + int own_gethrtime_update(struct timeval *ptr)   {    long long td,t,now; -  +  GETTIMEOFDAY(ptr);    RTSC(now); -  gettimeofday(ptr,NULL); +     td=((long long)ptr->tv_sec-hrtime_timeval_zero.tv_sec)*1000000000+    ((long long)ptr->tv_usec-hrtime_timeval_zero.tv_usec)*1000; -  +  +  hrtime_rtsc_last=now;    t=now-hrtime_rtsc_zero;    if (t) hrtime_conv=((long double)td)/t; -  +  +  return 1;   }    -  + /* this is very sensitive to the compiler; keep all crap */ +    long long gethrtime()   {    long long now; -  struct timeval dummy; +  struct timeval tv;    -  if (hrtime_conv==0.0) own_gethrtime_update(&dummy); +  if (hrtime_conv==0.0) +  { +  if (!own_gethrtime_update(&tv)) /* not calibrated yet */ +  { +  return +  hrtime_max= +  ((long long)tv.tv_sec-hrtime_timeval_zero.tv_sec)*1000000000+ +  ((long long)tv.tv_usec-hrtime_timeval_zero.tv_usec)*1000; +  } +  }       RTSC(now); -  return (long long) ( (long double)now * hrtime_conv ); +  +  if (now-hrtime_rtsc_last > 2000000000) +  { +  own_gethrtime_update(&tv); +  return gethrtime();    }    -  +  now = (long long) ( (long double)(now-hrtime_rtsc_zero) * hrtime_conv ); +  +  if (now<hrtime_max) now=hrtime_max; +  return hrtime_max=now; + } +  + #include <stdio.h> +    int main()   {    struct timeval tv1,tv2;
2741:    own_gethrtime_init();       usleep(10); +  own_gethrtime_update(&tv2); +     t1=gethrtime();       gettimeofday(&tv1,NULL);    for (;;) /* busy loop */    { -  gettimeofday(&tv2,NULL); +  GETTIMEOFDAY(&tv2);    td=((long long)tv2.tv_sec-tv1.tv_sec)*1000000000+    ((long long)tv2.tv_usec-tv1.tv_usec)*1000;    if (td>1000000) break;    }    t2=gethrtime();    -  + /* printf("t2-t1=%lld\n",t2-t1); */ +     if (t2==hrtime_rtsc_zero ||    t2-t1>1100000 ||    t2-t1<900000) return 1;       return 0; - } -  ], pike_cv_own_gethrtime_rdtsc=yes, + }], pike_cv_own_gethrtime_rdtsc=yes,    pike_cv_own_gethrtime_rdtsc=no, pike_cv_own_gethrtime_rdtsc=no)    ])    if test "x$pike_cv_own_gethrtime_rdtsc" = "xyes"; then