From bbc16cb0e0f24eea7283ba99dadca78893e2b348 Mon Sep 17 00:00:00 2001 From: "Mirar (Pontus Hagland)" <pike@sort.mirar.org> Date: Tue, 29 Aug 2000 15:40:14 +0200 Subject: [PATCH] gethrtime for non-solaris x586 implemented [bug 101] Rev: src/acconfig.h:1.65 Rev: src/backend.c:1.58 Rev: src/builtin_functions.c:1.306 Rev: src/configure.in:1.412 Rev: src/main.c:1.101 Rev: src/port.c:1.31 Rev: src/port.h:1.30 --- src/acconfig.h | 11 +++++- src/backend.c | 8 ++++- src/builtin_functions.c | 11 ++++-- src/configure.in | 79 ++++++++++++++++++++++++++++++++++++++++- src/main.c | 6 +++- src/port.c | 67 +++++++++++++++++++++++++++++++++- src/port.h | 10 +++++- 7 files changed, 183 insertions(+), 9 deletions(-) diff --git a/src/acconfig.h b/src/acconfig.h index eb668abeb3..05b620e37d 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 f62507ecf1..d26611fcfb 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 592dfa0f81..f6cb28426e 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 f8ca3bed70..07b1445df6 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 d974762cd7..2b089d50b5 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 5505319961..7b30a68cee 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 181f2cc847..e7ea1d38b8 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 -- GitLab