From b038beb7245877b71e30e782ddd6c86d82d11d17 Mon Sep 17 00:00:00 2001
From: Craig Tiller <ctiller@google.com>
Date: Tue, 7 Feb 2017 08:28:51 -0800
Subject: [PATCH] Add counters for mutex acquisitions, expose in bm_fullstack

---
 Makefile                                 |  8 +++++
 build.yaml                               |  3 ++
 src/core/lib/support/sync_posix.c        |  7 ++++
 test/cpp/microbenchmarks/bm_fullstack.cc | 46 +++++++++++++++++++-----
 tools/run_tests/generated/configs.json   |  3 ++
 tools/run_tests/generated/tests.json     | 34 ++++++++++++++++++
 6 files changed, 92 insertions(+), 9 deletions(-)

diff --git a/Makefile b/Makefile
index 0413cc0e009..3d8f7e6a432 100644
--- a/Makefile
+++ b/Makefile
@@ -212,6 +212,14 @@ CPPFLAGS_mutrace = -O3 -fno-omit-frame-pointer
 LDFLAGS_mutrace = -rdynamic
 DEFINES_mutrace = NDEBUG
 
+VALID_CONFIG_counters = 1
+CC_counters = $(DEFAULT_CC)
+CXX_counters = $(DEFAULT_CXX)
+LD_counters = $(DEFAULT_CC)
+LDXX_counters = $(DEFAULT_CXX)
+CPPFLAGS_counters = -O2 -DGPR_MU_COUNTERS
+DEFINES_counters = NDEBUG
+
 
 
 # General settings.
diff --git a/build.yaml b/build.yaml
index 456db28cef4..a13ba05b990 100644
--- a/build.yaml
+++ b/build.yaml
@@ -3825,6 +3825,9 @@ configs:
   basicprof:
     CPPFLAGS: -O2 -DGRPC_BASIC_PROFILER -DGRPC_TIMERS_RDTSC
     DEFINES: NDEBUG
+  counters:
+    CPPFLAGS: -O2 -DGPR_MU_COUNTERS
+    DEFINES: NDEBUG
   dbg:
     CPPFLAGS: -O0
     DEFINES: _DEBUG DEBUG
diff --git a/src/core/lib/support/sync_posix.c b/src/core/lib/support/sync_posix.c
index dcb0969a4ea..de0f0484b57 100644
--- a/src/core/lib/support/sync_posix.c
+++ b/src/core/lib/support/sync_posix.c
@@ -42,11 +42,18 @@
 #include <time.h>
 #include "src/core/lib/profiling/timers.h"
 
+#ifdef GPR_MU_COUNTERS
+gpr_atm grpc_mu_locks = 0;
+#endif
+
 void gpr_mu_init(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_init(mu, NULL) == 0); }
 
 void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
 
 void gpr_mu_lock(gpr_mu* mu) {
+#ifdef GPR_MU_COUNTERS
+  gpr_atm_no_barrier_fetch_add(&grpc_mu_locks, 1);
+#endif
   GPR_TIMER_BEGIN("gpr_mu_lock", 0);
   GPR_ASSERT(pthread_mutex_lock(mu) == 0);
   GPR_TIMER_END("gpr_mu_lock", 0);
diff --git a/test/cpp/microbenchmarks/bm_fullstack.cc b/test/cpp/microbenchmarks/bm_fullstack.cc
index c3e96c572c8..c5ace53ff9b 100644
--- a/test/cpp/microbenchmarks/bm_fullstack.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack.cc
@@ -94,7 +94,37 @@ static void ApplyCommonChannelArguments(ChannelArguments* c) {
   c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX);
 }
 
-class FullstackFixture {
+#ifdef GPR_MU_COUNTERS
+extern "C" gpr_atm grpc_mu_locks;
+#endif
+
+class BaseFixture {
+ public:
+  void Finish(benchmark::State& s) {
+    std::ostringstream out;
+    this->AddToLabel(out, s);
+#ifdef GPR_MU_COUNTERS
+    out << " locks/iteration:"
+        << ((double)(gpr_atm_no_barrier_load(&grpc_mu_locks) -
+                     mu_locks_at_start_) /
+            (double)s.iterations());
+#endif
+    auto label = out.str();
+    if (label.length() && label[0] == ' ') {
+      label = label.substr(1);
+    }
+    s.SetLabel(label);
+  }
+
+  virtual void AddToLabel(std::ostream& out, benchmark::State& s) = 0;
+
+ private:
+#ifdef GPR_MU_COUNTERS
+  const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&grpc_mu_locks);
+#endif
+};
+
+class FullstackFixture : public BaseFixture {
  public:
   FullstackFixture(Service* service, const grpc::string& address) {
     ServerBuilder b;
@@ -130,7 +160,7 @@ class TCP : public FullstackFixture {
  public:
   TCP(Service* service) : FullstackFixture(service, MakeAddress()) {}
 
-  void Finish(benchmark::State& state) {}
+  void AddToLabel(std::ostream& out, benchmark::State& state) {}
 
  private:
   static grpc::string MakeAddress() {
@@ -145,7 +175,7 @@ class UDS : public FullstackFixture {
  public:
   UDS(Service* service) : FullstackFixture(service, MakeAddress()) {}
 
-  void Finish(benchmark::State& state) {}
+  void AddToLabel(std::ostream& out, benchmark::State& state) override {}
 
  private:
   static grpc::string MakeAddress() {
@@ -157,7 +187,7 @@ class UDS : public FullstackFixture {
   }
 };
 
-class EndpointPairFixture {
+class EndpointPairFixture : public BaseFixture {
  public:
   EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints) {
     ServerBuilder b;
@@ -233,7 +263,7 @@ class SockPair : public EndpointPairFixture {
                                          "test", initialize_stuff.rq(), 8192)) {
   }
 
-  void Finish(benchmark::State& state) {}
+  void AddToLabel(std::ostream& out, benchmark::State& state) {}
 };
 
 class InProcessCHTTP2 : public EndpointPairFixture {
@@ -241,11 +271,9 @@ class InProcessCHTTP2 : public EndpointPairFixture {
   InProcessCHTTP2(Service* service)
       : EndpointPairFixture(service, MakeEndpoints()) {}
 
-  void Finish(benchmark::State& state) {
-    std::ostringstream out;
-    out << "writes/iteration:"
+  void AddToLabel(std::ostream& out, benchmark::State& state) {
+    out << " writes/iteration:"
         << ((double)stats_.num_writes / (double)state.iterations());
-    state.SetLabel(out.str());
   }
 
  private:
diff --git a/tools/run_tests/generated/configs.json b/tools/run_tests/generated/configs.json
index 091f5d98239..9173bd7c19c 100644
--- a/tools/run_tests/generated/configs.json
+++ b/tools/run_tests/generated/configs.json
@@ -66,5 +66,8 @@
   }, 
   {
     "config": "mutrace"
+  }, 
+  {
+    "config": "counters"
   }
 ]
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 4cc543962e4..34f777de166 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -39242,6 +39242,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39277,6 +39278,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39312,6 +39314,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39347,6 +39350,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39384,6 +39388,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39421,6 +39426,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39456,6 +39462,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39491,6 +39498,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39526,6 +39534,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39561,6 +39570,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39596,6 +39606,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39631,6 +39642,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39666,6 +39678,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39701,6 +39714,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39736,6 +39750,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39771,6 +39786,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39806,6 +39822,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39841,6 +39858,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39876,6 +39894,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39911,6 +39930,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39946,6 +39966,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -39983,6 +40004,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40020,6 +40042,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40055,6 +40078,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40090,6 +40114,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40125,6 +40150,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40160,6 +40186,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40195,6 +40222,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40230,6 +40258,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40265,6 +40294,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40300,6 +40330,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40335,6 +40366,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40370,6 +40402,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind", 
@@ -40405,6 +40438,7 @@
       "asan-noleaks", 
       "asan-trace-cmp", 
       "basicprof", 
+      "counters", 
       "dbg", 
       "gcov", 
       "helgrind",