X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Ftime.h;h=4d8997f0a9e30b2b33fcb083ea4eaa93cb526b8f;hb=b4e5e50fe;hp=3b89cf789fedeb2539e66c3521bef0c9bc716d85;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vppinfra/time.h b/src/vppinfra/time.h index 3b89cf789fe..4d8997f0a9e 100644 --- a/src/vppinfra/time.h +++ b/src/vppinfra/time.h @@ -39,6 +39,7 @@ #define included_time_h #include +#include typedef struct { @@ -58,6 +59,7 @@ typedef struct /* Time stamp of call to clib_time_init call. */ u64 init_cpu_time; + f64 init_reference_time; u64 last_verify_cpu_time; @@ -65,8 +67,14 @@ typedef struct f64 last_verify_reference_time; u32 log2_clocks_per_second, log2_clocks_per_frequency_verify; + + /* Damping constant */ + f64 damping_constant; + } clib_time_t; +format_function_t format_clib_time; + /* Return CPU time stamp as 64bit number. */ #if defined(__x86_64__) || defined(i386) always_inline u64 @@ -114,6 +122,16 @@ clib_cpu_time_now (void) return (u64) lo + ((u64) hi2 << (u64) 32); } +#elif defined (__aarch64__) +always_inline u64 +clib_cpu_time_now (void) +{ + u64 vct; + /* User access to cntvct_el0 is enabled in Linux kernel since 3.12. */ + asm volatile ("mrs %0, cntvct_el0":"=r" (vct)); + return vct; +} + #elif defined (__arm__) #if defined(__ARM_ARCH_8A__) always_inline u64 @@ -164,16 +182,14 @@ clib_cpu_time_now (void) return ((u64) h << 32) | l; } -#elif defined (__aarch64__) +#elif defined(_mips) && __mips == 64 + always_inline u64 clib_cpu_time_now (void) { - u64 tsc; - - /* Works on Cavium ThunderX. Other platforms: YMMV */ - asm volatile ("mrs %0, cntvct_el0":"=r" (tsc)); - - return tsc; + u64 result; + asm volatile ("rdhwr %0,$31\n":"=r" (result)); + return result; } #else @@ -183,21 +199,33 @@ clib_cpu_time_now (void) void clib_time_verify_frequency (clib_time_t * c); +/* Define it as the type returned by clib_time_now */ +typedef f64 clib_time_type_t; +typedef u64 clib_us_time_t; + +#define CLIB_US_TIME_PERIOD (1e-6) +#define CLIB_US_TIME_FREQ (1.0/CLIB_US_TIME_PERIOD) + always_inline f64 clib_time_now_internal (clib_time_t * c, u64 n) { u64 l = c->last_cpu_time; u64 t = c->total_cpu_time; + f64 rv; t += n - l; c->total_cpu_time = t; c->last_cpu_time = n; + rv = t * c->seconds_per_clock; if (PREDICT_FALSE ((c->last_cpu_time - c->last_verify_cpu_time) >> c->log2_clocks_per_frequency_verify)) clib_time_verify_frequency (c); - return t * c->seconds_per_clock; + return rv; } +/* Maximum f64 value as max clib_time */ +#define CLIB_TIME_MAX (1.7976931348623157e+308) + always_inline f64 clib_time_now (clib_time_t * c) { @@ -226,10 +254,14 @@ void clib_time_init (clib_time_t * c); always_inline f64 unix_time_now (void) { + struct timespec ts; +#ifdef __MACH__ + clock_gettime (CLOCK_REALTIME, &ts); +#else /* clock_gettime without indirect syscall uses GLIBC wrappers which we don't want. Just the bare metal, please. */ - struct timespec ts; syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts); +#endif return ts.tv_sec + 1e-9 * ts.tv_nsec; } @@ -238,10 +270,27 @@ always_inline u64 unix_time_now_nsec (void) { struct timespec ts; +#ifdef __MACH__ + clock_gettime (CLOCK_REALTIME, &ts); +#else syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts); +#endif return 1e9 * ts.tv_sec + ts.tv_nsec; } +always_inline void +unix_time_now_nsec_fraction (u32 * sec, u32 * nsec) +{ + struct timespec ts; +#ifdef __MACH__ + clock_gettime (CLOCK_REALTIME, &ts); +#else + syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts); +#endif + *sec = ts.tv_sec; + *nsec = ts.tv_nsec; +} + always_inline f64 unix_usage_now (void) { @@ -254,10 +303,12 @@ unix_usage_now (void) always_inline void unix_sleep (f64 dt) { - struct timespec t; - t.tv_sec = dt; - t.tv_nsec = 1e9 * dt; - nanosleep (&t, 0); + struct timespec ts, tsrem; + ts.tv_sec = dt; + ts.tv_nsec = 1e9 * (dt - (f64) ts.tv_sec); + + while (nanosleep (&ts, &tsrem) < 0) + ts = tsrem; } #else /* ! CLIB_UNIX */ @@ -274,6 +325,11 @@ unix_time_now_nsec (void) return 0; } +always_inline void +unix_time_now_nsec_fraction (u32 * sec, u32 * nsec) +{ +} + always_inline f64 unix_usage_now (void) {