quipper: Changes to build with external makefile

Previously, the external makefile was left behind and no longer updated
during the work to add ARC++ support to quipper. Now we bring it up to date
so it can be built externally again.

- Get rid of dependency on StringPrintf
- Add compat/ext for external build
- Implement Thread and Notification using C++ standard library classes
- Update log_level path in Makefile
- Link in libelf
- Explicitly include unistd.h in dso.cc
- Include new sources in makefile

BUG=chromium:623156
TEST=build successfully with Makefile.external

Change-Id: I815d18ba3a046cc758265985246a916c9bf7ae8b
Reviewed-on: https://chromium-review.googlesource.com/366470
Commit-Ready: Simon Que <sque@chromium.org>
Tested-by: Chong Jiang <chongjiang@chromium.org>
Reviewed-by: Chong Jiang <chongjiang@chromium.org>
diff --git a/chromiumos-wide-profiling/Makefile.external b/chromiumos-wide-profiling/Makefile.external
index 1dd2961..a88d6fa 100644
--- a/chromiumos-wide-profiling/Makefile.external
+++ b/chromiumos-wide-profiling/Makefile.external
@@ -12,25 +12,27 @@
 PC_LIBS := $(shell $(PKG_CONFIG) --libs $(PC_DEPS))
 
 CXXFLAGS += -std=c++11 -g -Wall -Werror -Wall -Wno-error
-CPPFLAGS += -Imybase -I. -I.. $(PC_CFLAGS)
-LDLIBS += -lpthread -lgcov $(PC_LIBS)
+CPPFLAGS += -Imybase -Icompat/ext -I. -I.. $(PC_CFLAGS)
+LDLIBS += -lpthread -lgcov -lelf $(PC_LIBS)
 
 MAIN_SOURCES = quipper.cc perf_converter.cc
 PROGRAMS = $(MAIN_SOURCES:.cc=)
 
 LIBRARY_SOURCES = \
 	address_mapper.cc buffer_reader.cc buffer_writer.cc \
-	conversion_utils.cc compat/log_level.cc data_reader.cc data_writer.cc \
-	file_reader.cc mybase/base/logging.cc perf_option_parser.cc \
-	perf_data_utils.cc perf_parser.cc perf_protobuf_io.cc perf_reader.cc \
-	perf_recorder.cc perf_serializer.cc perf_stat_parser.cc \
-	run_command.cc sample_info_reader.cc scoped_temp_path.cc utils.cc
+	conversion_utils.cc compat/ext/detail/log_level.cc data_reader.cc \
+	data_writer.cc dso.cc file_reader.cc huge_pages_mapping_deducer.cc \
+	mybase/base/logging.cc perf_option_parser.cc perf_data_utils.cc \
+	perf_parser.cc perf_protobuf_io.cc perf_reader.cc perf_recorder.cc \
+	perf_serializer.cc perf_stat_parser.cc run_command.cc \
+	sample_info_reader.cc scoped_temp_path.cc utils.cc
 GENERATED_SOURCES = perf_data.pb.cc perf_stat.pb.cc
 GENERATED_HEADERS = $(GENERATED_SOURCES:.pb.cc=.pb.h)
 
 COMMON_SOURCES = $(LIBRARY_SOURCES) $(GENERATED_SOURCES)
 COMMON_OBJECTS = $(COMMON_SOURCES:.cc=.o)
-TEST_COMMON_SOURCES = perf_test_files.cc test_perf_data.cc test_utils.cc
+TEST_COMMON_SOURCES = \
+	dso_test_utils.cc perf_test_files.cc test_perf_data.cc test_utils.cc
 TEST_COMMON_OBJECTS = $(TEST_COMMON_SOURCES:.cc=.o)
 
 INTEGRATION_TEST_SOURCES = conversion_utils_test.cc
@@ -40,10 +42,10 @@
 	file_reader_test.cc perf_data_utils_test.cc perf_option_parser_test.cc \
 	perf_parser_test.cc perf_reader_test.cc perf_serializer_test.cc \
 	perf_stat_parser_test.cc run_command_test.cc \
-	sample_info_reader_test.cc scoped_temp_path_test.cc utils_test.cc
-
+	sample_info_reader_test.cc scoped_temp_path_test.cc utils_test.cc \
+	huge_pages_mapping_deducer_test.cc
 TEST_SOURCES = $(INTEGRATION_TEST_SOURCES) $(PERF_RECORDER_TEST_SOURCES) \
-	       $(UNIT_TEST_SOURCES) $(TEST_COMMON_SOURCES) test_runner.cc
+	$(UNIT_TEST_SOURCES) $(TEST_COMMON_SOURCES) test_runner.cc
 TEST_OBJECTS = $(TEST_SOURCES:.cc=.o)
 
 ALL_SOURCES = $(MAIN_SOURCES) $(COMMON_SOURCES) $(TEST_SOURCES)
@@ -87,7 +89,7 @@
 	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 UNIT_TEST_OBJECTS = $(UNIT_TEST_SOURCES:.cc=.o) test_runner.o
-unit_tests: LDLIBS += -lgtest
+unit_tests: LDLIBS += -lgtest -lcap
 unit_tests: %: $(COMMON_OBJECTS) $(TEST_COMMON_OBJECTS) $(UNIT_TEST_OBJECTS)
 	$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
diff --git a/chromiumos-wide-profiling/compat/cros/detail/string.h b/chromiumos-wide-profiling/compat/cros/detail/string.h
index cdfd47a..b61ebd3 100644
--- a/chromiumos-wide-profiling/compat/cros/detail/string.h
+++ b/chromiumos-wide-profiling/compat/cros/detail/string.h
@@ -5,8 +5,4 @@
 #ifndef CHROMIUMOS_WIDE_PROFILING_COMPAT_CROS_DETAIL_STRING_H_
 #define CHROMIUMOS_WIDE_PROFILING_COMPAT_CROS_DETAIL_STRING_H_
 
-#include <base/strings/stringprintf.h>
-
-using base::StringPrintf;
-
 #endif  // CHROMIUMOS_WIDE_PROFILING_COMPAT_CROS_DETAIL_STRING_H_
diff --git a/chromiumos-wide-profiling/compat/ext/detail/log_level.cc b/chromiumos-wide-profiling/compat/ext/detail/log_level.cc
new file mode 120000
index 0000000..370ffa2
--- /dev/null
+++ b/chromiumos-wide-profiling/compat/ext/detail/log_level.cc
@@ -0,0 +1 @@
+../../cros/detail/log_level.cc
\ No newline at end of file
diff --git a/chromiumos-wide-profiling/compat/ext/detail/proto.h b/chromiumos-wide-profiling/compat/ext/detail/proto.h
new file mode 120000
index 0000000..e51eff6
--- /dev/null
+++ b/chromiumos-wide-profiling/compat/ext/detail/proto.h
@@ -0,0 +1 @@
+../../cros/detail/proto.h
\ No newline at end of file
diff --git a/chromiumos-wide-profiling/compat/ext/detail/string.h b/chromiumos-wide-profiling/compat/ext/detail/string.h
new file mode 120000
index 0000000..5223b57
--- /dev/null
+++ b/chromiumos-wide-profiling/compat/ext/detail/string.h
@@ -0,0 +1 @@
+../../cros/detail/string.h
\ No newline at end of file
diff --git a/chromiumos-wide-profiling/compat/ext/detail/test.h b/chromiumos-wide-profiling/compat/ext/detail/test.h
new file mode 120000
index 0000000..26d625b
--- /dev/null
+++ b/chromiumos-wide-profiling/compat/ext/detail/test.h
@@ -0,0 +1 @@
+../../cros/detail/test.h
\ No newline at end of file
diff --git a/chromiumos-wide-profiling/compat/ext/detail/thread.h b/chromiumos-wide-profiling/compat/ext/detail/thread.h
new file mode 100644
index 0000000..3a6bde7
--- /dev/null
+++ b/chromiumos-wide-profiling/compat/ext/detail/thread.h
@@ -0,0 +1,62 @@
+// Copyright 2016 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMIUMOS_WIDE_PROFILING_COMPAT_EXT_DETAIL_THREAD_H_
+#define CHROMIUMOS_WIDE_PROFILING_COMPAT_EXT_DETAIL_THREAD_H_
+
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
+
+namespace quipper {
+
+class Thread : public quipper::compat::ThreadInterface {
+ public:
+  explicit Thread(const string& name_prefix) {}
+
+  void Start() override {
+    thread_ = std::thread(&Thread::Run, this);
+  }
+
+  void Join() override {
+    thread_.join();
+  }
+
+  pid_t tid() override {
+    return thread_.native_handle();
+  }
+
+ protected:
+  void Run() override = 0;
+
+ private:
+  std::thread thread_;
+};
+
+class Notification : public quipper::compat::NotificationInterface {
+ public:
+  void Wait() override {
+    std::unique_lock<std::mutex> lock(mutex_);
+    event_.wait(lock);
+  }
+
+  bool WaitWithTimeout(int timeout_ms) override {
+    std::unique_lock<std::mutex> lock(mutex_);
+    return event_.wait_for(lock, std::chrono::milliseconds(timeout_ms)) ==
+        std::cv_status::no_timeout;
+  }
+
+  void Notify() override {
+    event_.notify_all();
+  }
+
+ private:
+  std::condition_variable event_;
+  std::mutex mutex_;
+};
+
+}  // namespace quipper
+
+#endif  // CHROMIUMOS_WIDE_PROFILING_COMPAT_EXT_DETAIL_THREAD_H_
diff --git a/chromiumos-wide-profiling/dso.cc b/chromiumos-wide-profiling/dso.cc
index 6985a6d..23618f8 100644
--- a/chromiumos-wide-profiling/dso.cc
+++ b/chromiumos-wide-profiling/dso.cc
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <algorithm>
 #include <vector>
diff --git a/chromiumos-wide-profiling/dso_test_utils.cc b/chromiumos-wide-profiling/dso_test_utils.cc
index 05ca283..4d2b139 100644
--- a/chromiumos-wide-profiling/dso_test_utils.cc
+++ b/chromiumos-wide-profiling/dso_test_utils.cc
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <unistd.h>
 
 #include <vector>
 
diff --git a/chromiumos-wide-profiling/perf_parser.cc b/chromiumos-wide-profiling/perf_parser.cc
index 7bbbe83..dda79ca 100644
--- a/chromiumos-wide-profiling/perf_parser.cc
+++ b/chromiumos-wide-profiling/perf_parser.cc
@@ -14,6 +14,7 @@
 #include <algorithm>
 #include <memory>
 #include <set>
+#include <sstream>
 
 #include "base/logging.h"
 
@@ -354,7 +355,9 @@
   for (PidTid pidtid : dso_info.threads) {
     u32 pid, tid;
     std::tie(pid, tid) = pidtid;
-    string dso_path = StringPrintf("/proc/%d/root/%s", tid, dso_name.c_str());
+    stringstream dso_path_stream;
+    dso_path_stream << "/proc/" << tid << "/root/" << dso_name;
+    string dso_path = dso_path_stream.str();
     if (ReadElfBuildIdIfSameInode(dso_path, dso_info, &buildid_bin)) {
       return buildid_bin;
     }
@@ -364,8 +367,10 @@
       continue;
     last_pid = pid;
     // Try the parent process:
-    dso_path = StringPrintf("/proc/%d/root/%s", pid, dso_name.c_str());
-    if (ReadElfBuildIdIfSameInode(dso_path, dso_info, &buildid_bin)) {
+    stringstream parent_dso_path_stream;
+    parent_dso_path_stream << "/proc/" << pid << "/root/" << dso_name;
+    string parent_dso_path = parent_dso_path_stream.str();
+    if (ReadElfBuildIdIfSameInode(parent_dso_path, dso_info, &buildid_bin)) {
       return buildid_bin;
     }
   }