diff --git a/BUILD b/BUILD index 25b26b7b244..d612d9c1ea4 100644 --- a/BUILD +++ b/BUILD @@ -51,6 +51,7 @@ cc_library( "src/core/support/string.h", "src/core/support/string_win32.h", "src/core/support/thd_internal.h", + "src/core/support/time_precise.h", "src/core/support/alloc.c", "src/core/support/cmdline.c", "src/core/support/cpu_iphone.c", @@ -208,7 +209,6 @@ cc_library( "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer_queue.h", @@ -477,7 +477,6 @@ cc_library( "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer_queue.h", @@ -992,6 +991,7 @@ objc_library( "src/core/support/string.h", "src/core/support/string_win32.h", "src/core/support/thd_internal.h", + "src/core/support/time_precise.h", ], includes = [ "include", @@ -1232,7 +1232,6 @@ objc_library( "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer_queue.h", diff --git a/build.json b/build.json index 1efaafdb52d..dec724629e3 100644 --- a/build.json +++ b/build.json @@ -181,7 +181,6 @@ "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer_queue.h", @@ -404,7 +403,8 @@ "src/core/support/stack_lockfree.h", "src/core/support/string.h", "src/core/support/string_win32.h", - "src/core/support/thd_internal.h" + "src/core/support/thd_internal.h", + "src/core/support/time_precise.h" ], "src": [ "src/core/support/alloc.c", diff --git a/gRPC.podspec b/gRPC.podspec index f6d09dbaa62..55f72c93d88 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -68,6 +68,7 @@ Pod::Spec.new do |s| 'src/core/support/grpc_string.h', 'src/core/support/string_win32.h', 'src/core/support/thd_internal.h', + 'src/core/support/time_precise.h', 'grpc/support/alloc.h', 'grpc/support/atm.h', 'grpc/support/atm_gcc_atomic.h', @@ -210,7 +211,6 @@ Pod::Spec.new do |s| 'src/core/json/json_reader.h', 'src/core/json/json_writer.h', 'src/core/profiling/timers.h', - 'src/core/profiling/timers_preciseclock.h', 'src/core/statistics/census_interface.h', 'src/core/statistics/census_rpc_stats.h', 'src/core/surface/byte_buffer_queue.h', @@ -404,6 +404,7 @@ Pod::Spec.new do |s| 'src/core/support/string.h', 'src/core/support/string_win32.h', 'src/core/support/thd_internal.h', + 'src/core/support/time_precise.h', 'src/core/security/auth_filters.h', 'src/core/security/base64.h', 'src/core/security/credentials.h', @@ -482,7 +483,6 @@ Pod::Spec.new do |s| 'src/core/json/json_reader.h', 'src/core/json/json_writer.h', 'src/core/profiling/timers.h', - 'src/core/profiling/timers_preciseclock.h', 'src/core/statistics/census_interface.h', 'src/core/statistics/census_rpc_stats.h', 'src/core/surface/byte_buffer_queue.h', diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h index 4ef9c764592..f8ed893bc02 100644 --- a/include/grpc/support/time.h +++ b/include/grpc/support/time.h @@ -52,6 +52,9 @@ typedef enum { /* Realtime clock. May jump forwards or backwards. Settable by the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */ GPR_CLOCK_REALTIME, + /* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch + undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */ + GPR_CLOCK_PRECISE, /* Unmeasurable clock type: no base, created by taking the difference between two times */ GPR_TIMESPAN diff --git a/src/core/profiling/basic_timers.c b/src/core/profiling/basic_timers.c index ae37f584ebb..4b6a0d2f56b 100644 --- a/src/core/profiling/basic_timers.c +++ b/src/core/profiling/basic_timers.c @@ -36,7 +36,6 @@ #ifdef GRPC_BASIC_PROFILER #include "src/core/profiling/timers.h" -#include "src/core/profiling/timers_preciseclock.h" #include #include @@ -53,7 +52,7 @@ typedef enum { } marker_type; typedef struct grpc_timer_entry { - grpc_precise_clock tm; + gpr_timespec tm; int tag; const char* tagstr; marker_type type; @@ -71,9 +70,8 @@ static void log_report() { int i; for (i = 0; i < count; i++) { grpc_timer_entry* entry = &(log[i]); - printf("GRPC_LAT_PROF " GRPC_PRECISE_CLOCK_FORMAT - " %p %c %d(%s) %p %s %d\n", - GRPC_PRECISE_CLOCK_PRINTF_ARGS(&entry->tm), + printf("GRPC_LAT_PROF %ld.%09d %p %c %d(%s) %p %s %d\n", + entry->tm.tv_sec, entry->tm.tv_nsec, (void*)(gpr_intptr)gpr_thd_currentid(), entry->type, entry->tag, entry->tagstr, entry->id, entry->file, entry->line); } @@ -93,7 +91,7 @@ static void grpc_timers_log_add(int tag, const char* tagstr, marker_type type, entry = &log[count++]; - grpc_precise_clock_now(&entry->tm); + entry->tm = gpr_now(GPR_CLOCK_PRECISE); entry->tag = tag; entry->tagstr = tagstr; entry->type = type; diff --git a/src/core/support/time_posix.c b/src/core/support/time_posix.c index 841485c4b4a..a2744002437 100644 --- a/src/core/support/time_posix.c +++ b/src/core/support/time_posix.c @@ -32,6 +32,7 @@ */ #include +#include #ifdef GPR_POSIX_TIME @@ -66,8 +67,14 @@ void gpr_time_init(void) {} gpr_timespec gpr_now(gpr_clock_type clock) { struct timespec now; GPR_ASSERT(clock != GPR_TIMESPAN); - clock_gettime(clockid_for_gpr_clock[clock], &now); - return gpr_from_timespec(now, clock); + if (clock == GPR_CLOCK_PRECISE) { + gpr_timespec ret; + gpr_precise_clock_now(&ret); + return ret; + } else { + clock_gettime(clockid_for_gpr_clock[clock], &now); + return gpr_from_timespec(now, clock); + } } #else /* For some reason Apple's OSes haven't implemented clock_gettime. */ @@ -104,6 +111,9 @@ gpr_timespec gpr_now(gpr_clock_type clock) { now.tv_sec = now_dbl * 1e-9; now.tv_nsec = now_dbl - now.tv_sec * 1e9; break; + case GPR_CLOCK_PRECISE: + gpr_precise_clock_now(&now); + break; case GPR_TIMESPAN: abort(); } diff --git a/src/core/profiling/timers_preciseclock.h b/src/core/support/time_precise.h similarity index 65% rename from src/core/profiling/timers_preciseclock.h rename to src/core/support/time_precise.h index 5c251b47e6f..574ebb84489 100644 --- a/src/core/profiling/timers_preciseclock.h +++ b/src/core/support/time_precise.h @@ -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 #include #include #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_ */ diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c index 7f64c80e276..f794855429b 100644 --- a/src/core/support/time_win32.c +++ b/src/core/support/time_win32.c @@ -38,6 +38,7 @@ #ifdef GPR_WIN32 #include +#include #include static LARGE_INTEGER g_start_time; @@ -68,6 +69,9 @@ gpr_timespec gpr_now(gpr_clock_type clock) { now_tv.tv_sec = (time_t)now_dbl; now_tv.tv_nsec = (int)((now_dbl - (double)now_tv.tv_sec) * 1e9); break; + case GPR_CLOCK_PRECISE: + gpr_precise_clock_now(&now_tv); + break; } return now_tv; } diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 06f0f4ee834..7d5df66bc18 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -845,7 +845,6 @@ src/core/json/json_common.h \ src/core/json/json_reader.h \ src/core/json/json_writer.h \ src/core/profiling/timers.h \ -src/core/profiling/timers_preciseclock.h \ src/core/statistics/census_interface.h \ src/core/statistics/census_rpc_stats.h \ src/core/surface/byte_buffer_queue.h \ @@ -1058,6 +1057,7 @@ src/core/support/stack_lockfree.h \ src/core/support/string.h \ src/core/support/string_win32.h \ src/core/support/thd_internal.h \ +src/core/support/time_precise.h \ src/core/support/alloc.c \ src/core/support/cmdline.c \ src/core/support/cpu_iphone.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 7b57096b7d3..084523cca4e 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -12168,7 +12168,8 @@ "src/core/support/stack_lockfree.h", "src/core/support/string.h", "src/core/support/string_win32.h", - "src/core/support/thd_internal.h" + "src/core/support/thd_internal.h", + "src/core/support/time_precise.h" ], "language": "c", "name": "gpr", @@ -12242,6 +12243,7 @@ "src/core/support/thd_win32.c", "src/core/support/time.c", "src/core/support/time_posix.c", + "src/core/support/time_precise.h", "src/core/support/time_win32.c", "src/core/support/tls_pthread.c" ] @@ -12339,7 +12341,6 @@ "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/security/auth_filters.h", "src/core/security/base64.h", "src/core/security/credentials.h", @@ -12542,7 +12543,6 @@ "src/core/profiling/basic_timers.c", "src/core/profiling/stap_timers.c", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/security/auth_filters.h", "src/core/security/base64.c", "src/core/security/base64.h", @@ -12818,7 +12818,6 @@ "src/core/json/json_reader.h", "src/core/json/json_writer.h", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer_queue.h", @@ -13006,7 +13005,6 @@ "src/core/profiling/basic_timers.c", "src/core/profiling/stap_timers.c", "src/core/profiling/timers.h", - "src/core/profiling/timers_preciseclock.h", "src/core/statistics/census_interface.h", "src/core/statistics/census_rpc_stats.h", "src/core/surface/byte_buffer.c", diff --git a/vsprojects/gpr/gpr.vcxproj b/vsprojects/gpr/gpr.vcxproj index 83c295625d8..3f8f554fd31 100644 --- a/vsprojects/gpr/gpr.vcxproj +++ b/vsprojects/gpr/gpr.vcxproj @@ -158,6 +158,7 @@ + diff --git a/vsprojects/gpr/gpr.vcxproj.filters b/vsprojects/gpr/gpr.vcxproj.filters index 64b90924ab4..b6ac061e05f 100644 --- a/vsprojects/gpr/gpr.vcxproj.filters +++ b/vsprojects/gpr/gpr.vcxproj.filters @@ -218,6 +218,9 @@ src\core\support + + src\core\support + diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index b17eea9235d..1fa7e4b4f13 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -307,7 +307,6 @@ - diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index a955e9e9934..b22818aebd0 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -680,9 +680,6 @@ src\core\profiling - - src\core\profiling - src\core\statistics diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index a692c48f81d..3883a328e09 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -290,7 +290,6 @@ - diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index 1c4036d464b..d12abc0ad70 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -578,9 +578,6 @@ src\core\profiling - - src\core\profiling - src\core\statistics