|
|
|
@ -31,65 +31,63 @@ |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifndef GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H |
|
|
|
|
#define GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H |
|
|
|
|
#ifndef GRPC_CORE_SUPPORT_TIME_PRECISE_H_ |
|
|
|
|
#define GRPC_CORE_SUPPORT_TIME_PRECISE_H_ |
|
|
|
|
|
|
|
|
|
#include <grpc/support/sync.h> |
|
|
|
|
#include <grpc/support/time.h> |
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
|
#ifdef GRPC_TIMERS_RDTSC |
|
|
|
|
typedef long long int grpc_precise_clock; |
|
|
|
|
#if defined(__i386__) |
|
|
|
|
static void grpc_precise_clock_now(grpc_precise_clock *clk) { |
|
|
|
|
grpc_precise_clock ret; |
|
|
|
|
static void gpr_get_cycle_counter(long long int *clk) { |
|
|
|
|
long long int ret; |
|
|
|
|
__asm__ volatile("rdtsc" : "=A"(ret)); |
|
|
|
|
*clk = ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------
|
|
|
|
|
#elif defined(__x86_64__) || defined(__amd64__) |
|
|
|
|
static void grpc_precise_clock_now(grpc_precise_clock *clk) { |
|
|
|
|
static void gpr_get_cycle_counter(long long int *clk) { |
|
|
|
|
unsigned long long low, high; |
|
|
|
|
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); |
|
|
|
|
*clk = (high << 32) | low; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static gpr_once precise_clock_init = GPR_ONCE_INIT; |
|
|
|
|
static double cycles_per_second = 0.0; |
|
|
|
|
static void grpc_precise_clock_init() { |
|
|
|
|
static long long cycles_per_second = 0; |
|
|
|
|
static void gpr_precise_clock_init() { |
|
|
|
|
time_t start = time(NULL); |
|
|
|
|
grpc_precise_clock start_time; |
|
|
|
|
grpc_precise_clock end_time; |
|
|
|
|
gpr_precise_clock start_cycle; |
|
|
|
|
gpr_precise_clock end_cycle; |
|
|
|
|
while (time(NULL) == start) |
|
|
|
|
; |
|
|
|
|
grpc_precise_clock_now(&start_time); |
|
|
|
|
gpr_get_cycle_counter(&start_cycle); |
|
|
|
|
while (time(NULL) == start + 1) |
|
|
|
|
; |
|
|
|
|
grpc_precise_clock_now(&end_time); |
|
|
|
|
cycles_per_second = end_time - start_time; |
|
|
|
|
gpr_get_cycle_counter(&end_cycle); |
|
|
|
|
cycles_per_second = end_cycle - start_cycle; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static double grpc_precise_clock_scaling_factor() { |
|
|
|
|
gpr_once_init(&precise_clock_init, grpc_precise_clock_init); |
|
|
|
|
return 1e6 / cycles_per_second; |
|
|
|
|
} |
|
|
|
|
#define GRPC_PRECISE_CLOCK_FORMAT "%f" |
|
|
|
|
#define GRPC_PRECISE_CLOCK_PRINTF_ARGS(clk) \ |
|
|
|
|
(*(clk)*grpc_precise_clock_scaling_factor()) |
|
|
|
|
#else |
|
|
|
|
typedef struct grpc_precise_clock grpc_precise_clock; |
|
|
|
|
struct grpc_precise_clock { |
|
|
|
|
gpr_timespec clock; |
|
|
|
|
}; |
|
|
|
|
static void grpc_precise_clock_now(grpc_precise_clock* clk) { |
|
|
|
|
clk->clock = gpr_now(GPR_CLOCK_REALTIME); |
|
|
|
|
|
|
|
|
|
static void gpr_precise_clock_now(gpr_timespec *clk) { |
|
|
|
|
long long int counter; |
|
|
|
|
gpr_get_cycle_counter(&counter); |
|
|
|
|
clk->clock = GPR_CLOCK_REALTIME; |
|
|
|
|
clk->tv_sec = counter / cycles_per_second; |
|
|
|
|
clk->tv_nsec = counter % cycles_per_second; |
|
|
|
|
} |
|
|
|
|
#define GRPC_PRECISE_CLOCK_FORMAT "%ld.%09d" |
|
|
|
|
#define GRPC_PRECISE_CLOCK_PRINTF_ARGS(clk) \ |
|
|
|
|
(clk)->clock.tv_sec, (clk)->clock.tv_nsec |
|
|
|
|
static void grpc_precise_clock_print(const grpc_precise_clock* clk, FILE* fp) { |
|
|
|
|
fprintf(fp, "%ld.%09d", clk->clock.tv_sec, clk->clock.tv_nsec); |
|
|
|
|
|
|
|
|
|
#else /* GRPC_TIMERS_RDTSC */ |
|
|
|
|
static void gpr_precise_clock_now(gpr_timespec *clk) { |
|
|
|
|
*clk = gpr_now(GPR_CLOCK_REALTIME); |
|
|
|
|
clk->clock_type = GPR_CLOCK_PRECISE; |
|
|
|
|
} |
|
|
|
|
#endif /* GRPC_TIMERS_RDTSC */ |
|
|
|
|
|
|
|
|
|
#endif /* GRPC_CORE_PROFILING_TIMERS_PRECISECLOCK_H */ |
|
|
|
|
#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_ */ |