Merge pull request #3048 from maxwell-demon/timespec

Move core/profiling/timers_preciseclock.h to core/support/ such that we
diff --git a/BUILD b/BUILD
index 25b26b7..d612d9c 100644
--- a/BUILD
+++ b/BUILD
@@ -51,6 +51,7 @@
     "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 @@
     "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 @@
     "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 @@
     "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 @@
     "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 1efaafd..dec7246 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 f6d09db..55f72c9 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -68,6 +68,7 @@
                       '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 @@
                       '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 @@
                               '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 @@
                               '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 4ef9c76..f8ed893 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -52,6 +52,9 @@
   /* 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 ae37f58..4b6a0d2 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 <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -53,7 +52,7 @@
 } 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 @@
   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 @@
 
   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 841485c..a274400 100644
--- a/src/core/support/time_posix.c
+++ b/src/core/support/time_posix.c
@@ -32,6 +32,7 @@
  */
 
 #include <grpc/support/port_platform.h>
+#include <src/core/support/time_precise.h>
 
 #ifdef GPR_POSIX_TIME
 
@@ -66,8 +67,14 @@
 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 @@
       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 64%
rename from src/core/profiling/timers_preciseclock.h
rename to src/core/support/time_precise.h
index 5c251b4..574ebb8 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 <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_ */
diff --git a/src/core/support/time_win32.c b/src/core/support/time_win32.c
index 7f64c80..f794855 100644
--- a/src/core/support/time_win32.c
+++ b/src/core/support/time_win32.c
@@ -38,6 +38,7 @@
 #ifdef GPR_WIN32
 
 #include <grpc/support/time.h>
+#include <src/core/support/time_precise.h>
 #include <sys/timeb.h>
 
 static LARGE_INTEGER g_start_time;
@@ -68,6 +69,9 @@
       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 06f0f4e..7d5df66 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -845,7 +845,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 \
@@ -1058,6 +1057,7 @@
 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 7b57096..084523c 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 83c2956..3f8f554 100644
--- a/vsprojects/gpr/gpr.vcxproj
+++ b/vsprojects/gpr/gpr.vcxproj
@@ -158,6 +158,7 @@
     <ClInclude Include="..\..\src\core\support\string.h" />
     <ClInclude Include="..\..\src\core\support\string_win32.h" />
     <ClInclude Include="..\..\src\core\support\thd_internal.h" />
+    <ClInclude Include="..\..\src\core\support\time_precise.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\core\support\alloc.c">
diff --git a/vsprojects/gpr/gpr.vcxproj.filters b/vsprojects/gpr/gpr.vcxproj.filters
index 64b9092..b6ac061 100644
--- a/vsprojects/gpr/gpr.vcxproj.filters
+++ b/vsprojects/gpr/gpr.vcxproj.filters
@@ -218,6 +218,9 @@
     <ClInclude Include="..\..\src\core\support\thd_internal.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\core\support\time_precise.h">
+      <Filter>src\core\support</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj
index b17eea9..1fa7e4b 100644
--- a/vsprojects/grpc/grpc.vcxproj
+++ b/vsprojects/grpc/grpc.vcxproj
@@ -307,7 +307,6 @@
     <ClInclude Include="..\..\src\core\json\json_reader.h" />
     <ClInclude Include="..\..\src\core\json\json_writer.h" />
     <ClInclude Include="..\..\src\core\profiling\timers.h" />
-    <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h" />
     <ClInclude Include="..\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h" />
diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters
index a955e9e..b22818a 100644
--- a/vsprojects/grpc/grpc.vcxproj.filters
+++ b/vsprojects/grpc/grpc.vcxproj.filters
@@ -680,9 +680,6 @@
     <ClInclude Include="..\..\src\core\profiling\timers.h">
       <Filter>src\core\profiling</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h">
-      <Filter>src\core\profiling</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>
diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
index a692c48..3883a32 100644
--- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
@@ -290,7 +290,6 @@
     <ClInclude Include="..\..\src\core\json\json_reader.h" />
     <ClInclude Include="..\..\src\core\json\json_writer.h" />
     <ClInclude Include="..\..\src\core\profiling\timers.h" />
-    <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h" />
     <ClInclude Include="..\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" />
     <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h" />
diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 1c4036d..d12abc0 100644
--- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -578,9 +578,6 @@
     <ClInclude Include="..\..\src\core\profiling\timers.h">
       <Filter>src\core\profiling</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h">
-      <Filter>src\core\profiling</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\statistics\census_interface.h">
       <Filter>src\core\statistics</Filter>
     </ClInclude>