From e12cf1123e8784ce6fe9d2ac14526331fbe2c555 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sun, 16 Aug 2015 17:27:25 +0200 Subject: [PATCH] add fallback rpcc implementation - use on arm, arm64 and any new platform - use faster integer math instead of double - use similar scale as rdtsc so that timeouts work --- common.h | 28 ++++++++++++++++++++++++++++ common_alpha.h | 1 + common_arm.h | 10 ---------- common_arm64.h | 10 ---------- common_ia64.h | 2 ++ common_mips64.h | 1 + common_power.h | 1 + common_sparc.h | 1 + common_x86.h | 1 + common_x86_64.h | 1 + 10 files changed, 36 insertions(+), 20 deletions(-) diff --git a/common.h b/common.h index 320adadcb..5998b5608 100644 --- a/common.h +++ b/common.h @@ -410,7 +410,35 @@ typedef char env_var_t[MAX_PATH]; typedef char* env_var_t; #define readenv(p, n) ((p)=getenv(n)) #endif + +#if !defined(RPCC_DEFINED) && !defined(OS_WINDOWS) +#ifdef _POSIX_MONOTONIC_CLOCK +#if defined(__GNUC_PREREQ) && __GLIBC_PREREQ(2, 17) // don't require -lrt +#define USE_MONOTONIC +#elif defined(OS_ANDROID) +#define USE_MONOTONIC #endif +#endif +/* use similar scale as x86 rdtsc for timeouts to work correctly */ +static inline unsigned long long rpcc(void){ +#ifdef USE_MONOTONIC + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (unsigned long long)ts.tv_sec * 1000000000ull + ts.tv_nsec; +#else + struct timeval tv; + gettimeofday(&tv,NULL); + return (unsigned long long)tv.tv_sec * 1000000000ull + tv.tv_usec * 1000; +#endif +} +#define RPCC_DEFINED +#define RPCC64BIT +#endif // !RPCC_DEFINED + +#ifndef RPCC_DEFINED +#error "rpcc() implementation is missing for your platform" +#endif +#endif // !ASSEMBLER #ifdef OS_LINUX #include "common_linux.h" diff --git a/common_alpha.h b/common_alpha.h index 845fb316a..86f58966a 100644 --- a/common_alpha.h +++ b/common_alpha.h @@ -89,6 +89,7 @@ static __inline unsigned int rpcc(void){ return r0; } +#define RPCC_DEFINED #define HALT ldq $0, 0($0) diff --git a/common_arm.h b/common_arm.h index 2dabd4d7f..7e0c02306 100644 --- a/common_arm.h +++ b/common_arm.h @@ -72,16 +72,6 @@ static void __inline blas_lock(volatile BLASULONG *address){ } -static inline unsigned long long rpcc(void){ - unsigned long long ret=0; - double v; - struct timeval tv; - gettimeofday(&tv,NULL); - v=(double) tv.tv_sec + (double) tv.tv_usec * 1e-6; - ret = (unsigned long long) ( v * 1000.0d ); - return ret; -} - static inline int blas_quickdivide(blasint x, blasint y){ return x / y; } diff --git a/common_arm64.h b/common_arm64.h index aa310c5f2..cc08fa75b 100644 --- a/common_arm64.h +++ b/common_arm64.h @@ -71,16 +71,6 @@ static void __inline blas_lock(volatile BLASULONG *address){ } -static inline unsigned long long rpcc(void){ - unsigned long long ret=0; - double v; - struct timeval tv; - gettimeofday(&tv,NULL); - v=(double) tv.tv_sec + (double) tv.tv_usec * 1e-6; - ret = (unsigned long long) ( v * 1000.0d ); - return ret; -} - static inline int blas_quickdivide(blasint x, blasint y){ return x / y; } diff --git a/common_ia64.h b/common_ia64.h index 8e92b5992..d1f210749 100644 --- a/common_ia64.h +++ b/common_ia64.h @@ -75,6 +75,7 @@ static __inline unsigned long rpcc(void) { __asm__ __volatile__ ("mov %0=ar.itc" : "=r"(clocks)); return clocks; } +#define RPCC_DEFINED static __inline unsigned long stmxcsr(void){ @@ -103,6 +104,7 @@ static __inline void blas_lock(volatile unsigned long *address){ static __inline unsigned int rpcc(void) { return __getReg(_IA64_REG_AR_ITC); } +#define RPCC_DEFINED static __inline unsigned int stmxcsr(void) { return __getReg(_IA64_REG_AR_FPSR); diff --git a/common_mips64.h b/common_mips64.h index 7cd86b375..bc1a52fb4 100644 --- a/common_mips64.h +++ b/common_mips64.h @@ -118,6 +118,7 @@ static inline unsigned int rpcc(void){ #endif return ret; } +#define RPCC_DEFINED #if defined(LOONGSON3A) || defined(LOONGSON3B) #ifndef NO_AFFINITY diff --git a/common_power.h b/common_power.h index e9b5cb630..3b9471a17 100644 --- a/common_power.h +++ b/common_power.h @@ -103,6 +103,7 @@ static inline unsigned long rpcc(void){ #endif } +#define RPCC_DEFINED #ifdef __64BIT__ #define RPCC64BIT diff --git a/common_sparc.h b/common_sparc.h index 87ef75276..8a16e3d3a 100644 --- a/common_sparc.h +++ b/common_sparc.h @@ -66,6 +66,7 @@ static __inline unsigned long rpcc(void){ return clocks; }; +#define RPCC_DEFINED #ifdef __64BIT__ #define RPCC64BIT diff --git a/common_x86.h b/common_x86.h index 99a723fd7..9506716ce 100644 --- a/common_x86.h +++ b/common_x86.h @@ -73,6 +73,7 @@ static __inline unsigned long long rpcc(void){ return ((unsigned long long)a + ((unsigned long long)d << 32)); }; +#define RPCC_DEFINED static __inline unsigned long getstackaddr(void){ unsigned long addr; diff --git a/common_x86_64.h b/common_x86_64.h index efb902416..3a02beefb 100644 --- a/common_x86_64.h +++ b/common_x86_64.h @@ -82,6 +82,7 @@ static __inline BLASULONG rpcc(void){ return ((BLASULONG)a + ((BLASULONG)d << 32)); } +#define RPCC_DEFINED #define RPCC64BIT