tests: add callgrind start/stop macros in benchmark programs

Change-Id: Ibd875f4275431ebcbeba2fffe319956580714553
Refs: #3610
diff --git a/tests/other/cs-benchmark.cpp b/tests/other/cs-benchmark.cpp
index fcd9d20..3e7a5a2 100644
--- a/tests/other/cs-benchmark.cpp
+++ b/tests/other/cs-benchmark.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+ * Copyright (c) 2014-2016,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,10 +24,13 @@
  */
 
 #include "table/cs.hpp"
-#include <ndn-cxx/security/key-chain.hpp>
 
 #include "tests/test-common.hpp"
 
+#ifdef HAVE_VALGRIND
+#include <valgrind/callgrind.h>
+#endif
+
 namespace nfd {
 namespace tests {
 
@@ -39,17 +42,26 @@
 #ifdef _DEBUG
     BOOST_TEST_MESSAGE("Benchmark compiled in debug mode is unreliable, "
                        "please compile in release mode.");
-#endif // _DEBUG
+#endif
 
     cs.setLimit(CS_CAPACITY);
   }
 
-  time::microseconds
-  timedRun(std::function<void()> f)
+  static time::microseconds
+  timedRun(const std::function<void()>& f)
   {
-    time::steady_clock::TimePoint t1 = time::steady_clock::now();
+#ifdef HAVE_VALGRIND
+    CALLGRIND_START_INSTRUMENTATION;
+#endif
+
+    auto t1 = time::steady_clock::now();
     f();
-    time::steady_clock::TimePoint t2 = time::steady_clock::now();
+    auto t2 = time::steady_clock::now();
+
+#ifdef HAVE_VALGRIND
+    CALLGRIND_STOP_INSTRUMENTATION;
+#endif
+
     return time::duration_cast<time::microseconds>(t2 - t1);
   }
 
@@ -84,7 +96,7 @@
     Name m_prefix;
   };
 
-  std::vector<shared_ptr<Interest>>
+  static std::vector<shared_ptr<Interest>>
   makeInterestWorkload(size_t count, const NameGenerator& genName = SimpleNameGenerator())
   {
     std::vector<shared_ptr<Interest>> workload(count);
@@ -95,7 +107,7 @@
     return workload;
   }
 
-  std::vector<shared_ptr<Data>>
+  static std::vector<shared_ptr<Data>>
   makeDataWorkload(size_t count, const NameGenerator& genName = SimpleNameGenerator())
   {
     std::vector<shared_ptr<Data>> workload(count);
@@ -108,7 +120,7 @@
 
 protected:
   Cs cs;
-  static const size_t CS_CAPACITY = 50000;
+  static constexpr size_t CS_CAPACITY = 50000;
 };
 
 BOOST_FIXTURE_TEST_SUITE(TableCsBenchmark, CsBenchmarkFixture)
@@ -116,8 +128,8 @@
 // find miss, then insert
 BOOST_AUTO_TEST_CASE(FindMissInsert)
 {
-  const size_t N_WORKLOAD = CS_CAPACITY * 2;
-  const size_t REPEAT = 4;
+  constexpr size_t N_WORKLOAD = CS_CAPACITY * 2;
+  constexpr size_t REPEAT = 4;
 
   std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_WORKLOAD);
   std::vector<shared_ptr<Data>> dataWorkload[REPEAT];
@@ -139,8 +151,8 @@
 // insert, then find hit
 BOOST_AUTO_TEST_CASE(InsertFindHit)
 {
-  const size_t N_WORKLOAD = CS_CAPACITY * 2;
-  const size_t REPEAT = 4;
+  constexpr size_t N_WORKLOAD = CS_CAPACITY * 2;
+  constexpr size_t REPEAT = 4;
 
   std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_WORKLOAD);
   std::vector<shared_ptr<Data>> dataWorkload[REPEAT];
@@ -162,8 +174,10 @@
 // find(leftmost) hit
 BOOST_AUTO_TEST_CASE(Leftmost)
 {
-  const size_t N_CHILDREN = 10;
-  const size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
+  constexpr size_t N_CHILDREN = 10;
+  constexpr size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
+  constexpr size_t REPEAT = 4;
+
   std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
   for (auto&& interest : interestWorkload) {
     interest->setChildSelector(0);
@@ -176,8 +190,6 @@
   }
   BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
 
-  const size_t REPEAT = 4;
-
   time::microseconds d = timedRun([&] {
     for (size_t j = 0; j < REPEAT; ++j) {
       for (const auto& interest : interestWorkload) {
@@ -191,8 +203,10 @@
 // find(rightmost) hit
 BOOST_AUTO_TEST_CASE(Rightmost)
 {
-  const size_t N_CHILDREN = 10;
-  const size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
+  constexpr size_t N_CHILDREN = 10;
+  constexpr size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
+  constexpr size_t REPEAT = 4;
+
   std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
   for (auto&& interest : interestWorkload) {
     interest->setChildSelector(1);
@@ -205,8 +219,6 @@
   }
   BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
 
-  const size_t REPEAT = 4;
-
   time::microseconds d = timedRun([&] {
     for (size_t j = 0; j < REPEAT; ++j) {
       for (const auto& interest : interestWorkload) {
diff --git a/tests/other/face-benchmark.cpp b/tests/other/face-benchmark.cpp
index afd4cf7..1dc6c37 100644
--- a/tests/other/face-benchmark.cpp
+++ b/tests/other/face-benchmark.cpp
@@ -32,6 +32,10 @@
 #include <fstream>
 #include <iostream>
 
+#ifdef HAVE_VALGRIND
+#include <valgrind/callgrind.h>
+#endif
+
 namespace nfd {
 namespace tests {
 
@@ -172,6 +176,10 @@
 int
 main(int argc, char** argv)
 {
+#ifdef _DEBUG
+  std::cerr << "Benchmark compiled in debug mode is unreliable, please compile in release mode.\n";
+#endif
+
   if (argc != 2) {
     std::cerr << "Usage: " << argv[0] << " <config-file>" << std::endl;
     return 2;
@@ -179,6 +187,9 @@
 
   try {
     nfd::tests::FaceBenchmark bench{argv[1]};
+#ifdef HAVE_VALGRIND
+    CALLGRIND_START_INSTRUMENTATION;
+#endif
     nfd::getGlobalIoService().run();
   }
   catch (const std::exception& e) {
diff --git a/tests/other/pit-fib-benchmark.cpp b/tests/other/pit-fib-benchmark.cpp
index e6c907f..85ffe5e 100644
--- a/tests/other/pit-fib-benchmark.cpp
+++ b/tests/other/pit-fib-benchmark.cpp
@@ -28,6 +28,10 @@
 
 #include "tests/test-common.hpp"
 
+#ifdef HAVE_VALGRIND
+#include <valgrind/callgrind.h>
+#endif
+
 namespace nfd {
 namespace tests {
 
@@ -38,6 +42,10 @@
     : m_fib(m_nameTree)
     , m_pit(m_nameTree)
   {
+#ifdef _DEBUG
+    BOOST_TEST_MESSAGE("Benchmark compiled in debug mode is unreliable, "
+                       "please compile in release mode.");
+#endif
   }
 
   void
@@ -113,6 +121,10 @@
   generatePacketsAndPopulateFib(nRoundTrip, nFibEntries, fibPrefixLength,
                                 interestNameLength, dataNameLength);
 
+#ifdef HAVE_VALGRIND
+  CALLGRIND_START_INSTRUMENTATION;
+#endif
+
   auto t1 = time::steady_clock::now();
 
   for (size_t i = 0; i < nRoundTrip + gap3 + gap4; ++i) {
@@ -133,6 +145,11 @@
   }
 
   auto t2 = time::steady_clock::now();
+
+#ifdef HAVE_VALGRIND
+  CALLGRIND_STOP_INSTRUMENTATION;
+#endif
+
   BOOST_TEST_MESSAGE(time::duration_cast<time::microseconds>(t2 - t1));
 }
 
diff --git a/wscript b/wscript
index 9f3a0cb..b029c75 100644
--- a/wscript
+++ b/wscript
@@ -109,6 +109,7 @@
       Logs.warn('Dropping privileges is not supported on this platform')
 
     conf.check_cxx(header_name='ifaddrs.h', mandatory=False)
+    conf.check_cxx(header_name='valgrind/valgrind.h', define_name='HAVE_VALGRIND', mandatory=False)
 
     boost_libs = 'system chrono program_options random thread log log_setup'
     if conf.options.with_tests: