diff --git a/src/acconfig.h b/src/acconfig.h index eb668abeb3849f15fb9769a45f0283efa5d05ce7..05b620e37da13b0d4dd6fd9e2d3184ad1acbc720 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -1,5 +1,5 @@ /* - * $Id: acconfig.h,v 1.64 2000/08/29 12:37:46 grubba Exp $ + * $Id: acconfig.h,v 1.65 2000/08/29 13:40:13 mirar Exp $ */ #ifndef MACHINE_H #define MACHINE_H @@ -152,6 +152,15 @@ /* Define if gettimeofday takes to arguments */ #undef GETTIMEOFDAY_TAKES_TWO_ARGS +/* Define if you have gethrtime */ +#undef HAVE_GETHRTIME + +/* Can we make our own gethrtime? */ +#undef OWN_GETHRTIME + +/* ... by using the RDTSC instruction? */ +#undef OWN_GETHRTIME_RDTSC + /* Define if you have a working, 8-bit-clean memcmp */ #undef HAVE_MEMCMP diff --git a/src/backend.c b/src/backend.c index f62507ecf18f4aa13a926365909e4a4f42c91ae6..d26611fcfbf20927c8fbaffc2cb1fd0b3c1e4ff8 100644 --- a/src/backend.c +++ b/src/backend.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: backend.c,v 1.57 2000/08/28 16:23:59 grubba Exp $"); +RCSID("$Id: backend.c,v 1.58 2000/08/29 13:40:13 mirar Exp $"); #include "fdlib.h" #include "backend.h" #include <errno.h> @@ -723,7 +723,13 @@ void backend(void) if(d_flag > 1) do_debug(); #endif +#ifndef OWN_GETHRTIME GETTIMEOFDAY(¤t_time); +#else + /* good place to run the gethrtime-conversion update + since we have to run gettimeofday anyway /Mirar */ + own_gethrtime_update(¤t_time); +#endif if(my_timercmp(&next_timeout, > , ¤t_time)) { diff --git a/src/builtin_functions.c b/src/builtin_functions.c index 592dfa0f81f5a39063abe431058d4639a735dc2c..f6cb28426e13367fc03a3306b3259bdf58f8ac82 100644 --- a/src/builtin_functions.c +++ b/src/builtin_functions.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: builtin_functions.c,v 1.305 2000/08/28 17:55:07 grubba Exp $"); +RCSID("$Id: builtin_functions.c,v 1.306 2000/08/29 13:40:13 mirar Exp $"); #include "interpret.h" #include "svalue.h" #include "pike_macros.h" @@ -4486,15 +4486,20 @@ PMOD_EXPORT void f_master(INT32 args) ref_push_object(master()); } -#ifdef HAVE_GETHRVTIME +#ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#endif + +#ifdef HAVE_GETHRVTIME PMOD_EXPORT void f_gethrvtime(INT32 args) { pop_n_elems(args); push_int64(gethrvtime()/1000); } +#endif +#ifdef HAVE_GETHRTIME PMOD_EXPORT void f_gethrtime(INT32 args) { pop_n_elems(args); @@ -4521,7 +4526,7 @@ PMOD_EXPORT void f_gethrtime(INT32 args) push_int64((tv.tv_sec * 1000000) + tv.tv_usec); #endif /* INT64 */ } -#endif /* HAVE_GETHRVTIME */ +#endif /* HAVE_GETHRTIME */ #ifdef PROFILING static void f_get_prof_info(INT32 args) diff --git a/src/configure.in b/src/configure.in index f8ca3bed70800118a6ea76f0f3786d4dc510a4a5..07b1445df65f1e9018188ee39e626b7375658c99 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.411 2000/08/29 01:10:25 hubbe Exp $") +AC_REVISION("$Id: configure.in,v 1.412 2000/08/29 13:40:13 mirar Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -2161,6 +2161,83 @@ fi AC_MSG_RESULT($pike_cv_func_gettimeofday_has_two_args) +if test "x$ac_cv_func_gethrtime" != "xyes"; then + AC_MSG_CHECKING(if we can make gethrtime by the RDTSC instruction) + AC_CACHE_VAL(pike_cv_own_gethrtime_rdtsc, [ + AC_TRY_RUN([ +#include <unistd.h> +#include <sys/time.h> + +static long long hrtime_rtsc_zero; +static struct timeval hrtime_timeval_zero; +static long double hrtime_conv=0.0; + +#define RTSC(x) \ + __asm__ __volatile__ ( "rdtsc" \ + :"=a" (((unsigned long*)&x)[0]), \ + "=d" (((unsigned long*)&x)[1])) + +void own_gethrtime_init() +{ + RTSC(hrtime_rtsc_zero); + gettimeofday(&hrtime_timeval_zero,NULL); +} + +void own_gethrtime_update(struct timeval *ptr) +{ + long long td,t,now; + 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; + t=now-hrtime_rtsc_zero; + if (t) hrtime_conv=((long double)td)/t; +} + +long long gethrtime() +{ + long long now; + struct timeval dummy; + + if (hrtime_conv==0.0) own_gethrtime_update(&dummy); + + RTSC(now); + return (long long) ( (long double)now * hrtime_conv ); +} + +int main() +{ + struct timeval tv1,tv2; + long long td,t2; + own_gethrtime_init(); + + gettimeofday(&tv1,NULL); + for (;;) /* busy loop */ + { + gettimeofday(&tv2,NULL); + 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(); + + if (t2!=hrtime_rtsc_zero) return 0; + + return 1; +} + ],pike_cv_own_gethrtime_rdtsc=yes, + pike_cv_own_gethrtime_rdtsc=no) + ]) + if test "x$pike_cv_own_gethrtime_rdtsc" = "xyes"; then + AC_MSG_RESULT(yes) + AC_DEFINE(OWN_GETHRTIME) + AC_DEFINE(OWN_GETHRTIME_RDTSC) + AC_DEFINE(HAVE_GETHRTIME) + else + AC_MSG_RESULT([no]) + fi +fi + AC_MSG_CHECKING(if struct tm has tm_gmtoff) AC_CACHE_VAL(pike_cv_struct_tm_has_gmtoff,[ diff --git a/src/main.c b/src/main.c index d974762cd7a4dca00bdb5b551f90b023dc457e7a..2b089d50b5a53f23ec5889158412144dc187a6dd 100644 --- a/src/main.c +++ b/src/main.c @@ -5,7 +5,7 @@ \*/ /**/ #include "global.h" -RCSID("$Id: main.c,v 1.100 2000/08/24 04:04:41 hubbe Exp $"); +RCSID("$Id: main.c,v 1.101 2000/08/29 13:40:14 mirar Exp $"); #include "fdlib.h" #include "backend.h" #include "module.h" @@ -152,6 +152,10 @@ int dbm_main(int argc, char **argv) #ifdef TRY_USE_MMX try_use_mmx=mmx_ok(); #endif +#ifdef OWN_GETHRTIME +/* initialize our own gethrtime conversion /Mirar */ + own_gethrtime_init(); +#endif ARGV=argv; diff --git a/src/port.c b/src/port.c index 55053199615aa7b49441b838eb2821fa16b372cc..7b30a68cee7b6f5cdcfeaa75d4cc2841707a3249 100644 --- a/src/port.c +++ b/src/port.c @@ -18,7 +18,7 @@ #include <float.h> #include <string.h> -RCSID("$Id: port.c,v 1.30 2000/08/29 12:34:02 grubba Exp $"); +RCSID("$Id: port.c,v 1.31 2000/08/29 13:40:14 mirar Exp $"); #ifdef sun time_t time PROT((time_t *)); @@ -638,3 +638,68 @@ PMOD_EXPORT INT32 EXTRACT_INT_(unsigned char *p) return a; } #endif + +#ifdef OWN_GETHRTIME + +#ifdef OWN_GETHRTIME_RDTSC + +static long long hrtime_rtsc_zero; +static long long hrtime_rtsc_last; +static struct timeval hrtime_timeval_zero; +static long double hrtime_conv=0.0; + +#define RTSC(x) \ + __asm__ __volatile__ ( "rdtsc" \ + :"=a" (((unsigned long*)&x)[0]), \ + "=d" (((unsigned long*)&x)[1])) + +void own_gethrtime_init() +{ + RTSC(hrtime_rtsc_zero); + hrtime_rtsc_last=hrtime_rtsc_zero; + GETTIMEOFDAY(&hrtime_timeval_zero); +} + +void own_gethrtime_update(struct timeval *ptr) +{ + long long td,t,now; + RTSC(now); + GETTIMEOFDAY(ptr); + 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; + +/* fixme: add time deviation detection; + when time is adjusted, this calculation isn't linear anymore, + so it might be best to reset it */ + +#if 0 + fprintf(stderr,"conv=%.8llg MHz=%.8llg\n",hrtime_conv,1000.0/hrtime_conv); +#endif +} + +long long gethrtime() +{ + long long now; + struct timeval dummy; + + if (hrtime_conv==0.0) own_gethrtime_update(&dummy); + + RTSC(now); + +/* 2 seconds between updates */ + if (now-hrtime_rtsc_last > 2000000000) + { + fprintf(stderr,"update: %.8llg\n",1e-9*(now-hrtime_rtsc_last)); + own_gethrtime_update(&dummy); + return gethrtime(); + } + + return (long long) ( (long double)now * hrtime_conv ); +} + +#endif + +#endif diff --git a/src/port.h b/src/port.h index 181f2cc847c219f85a19062563368f809580eaed..e7ea1d38b863e7f90fc8e675a96a98d748cd87a2 100644 --- a/src/port.h +++ b/src/port.h @@ -5,7 +5,7 @@ \*/ /* - * $Id: port.h,v 1.29 2000/06/30 09:46:14 grubba Exp $ + * $Id: port.h,v 1.30 2000/08/29 13:40:14 mirar Exp $ */ #ifndef PORT_H #define PORT_H @@ -221,4 +221,12 @@ static INLINE INT32 EXTRACT_INT_(unsigned char *p) unsigned long my_rand(void); void my_srand(long seed); +#ifdef OWN_GETHRTIME +void own_gethrtime_init(); +void own_gethrtime_update(struct timeval *ptr); +long long gethrtime(); + +#define hrtime_t long long +#endif + #endif