summaryrefslogtreecommitdiff
path: root/test/xray
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2018-06-12 03:29:39 +0000
committerDean Michael Berris <dberris@google.com>2018-06-12 03:29:39 +0000
commitda1b8bff539cef08140fb20b8e7ed0ae0c244df5 (patch)
treef09a7bcdd340024cbafb389b49a7f0cd6e1971dc /test/xray
parentf8a3f1ef5dc8840cbf554cbec32373ca935172f1 (diff)
[XRay][profiler] Part 4: Profiler Mode Wiring
Summary: This is part of the larger XRay Profiling Mode effort. This patch implements the wiring required to enable us to actually select the `xray-profiling` mode, and install the handlers to start measuring the time and frequency of the function calls in call stacks. The current way to get the profile information is by working with the XRay API to `__xray_process_buffers(...)`. In subsequent changes we'll implement profile saving to files, similar to how the FDR and basic modes operate, as well as means for converting this format into those that can be loaded/visualised as flame graphs. We will also be extending the accounting tool in LLVM to support stack-based function call accounting. We also continue with the implementation to support building small histograms of latencies for the `FunctionCallTrie::Node` type, to allow us to actually approximate the distribution of latencies per function. Depends on D45758 and D46998. Reviewers: eizan, kpw, pelikan Reviewed By: kpw Subscribers: llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D44620 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@334469 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/xray')
-rw-r--r--test/xray/TestCases/Posix/c-test.cc2
-rw-r--r--test/xray/TestCases/Posix/profiling-multi-threaded.cc53
-rw-r--r--test/xray/TestCases/Posix/profiling-single-threaded.cc58
3 files changed, 112 insertions, 1 deletions
diff --git a/test/xray/TestCases/Posix/c-test.cc b/test/xray/TestCases/Posix/c-test.cc
index f8f5775d1..de9b58985 100644
--- a/test/xray/TestCases/Posix/c-test.cc
+++ b/test/xray/TestCases/Posix/c-test.cc
@@ -1,4 +1,4 @@
-// RUN: %clang_xray -g -o %t %s
+// RUN: %clang_xray -g -fxray-modes=xray-basic,xray-fdr,xray-profiling -o %t %s
// RUN: rm xray-log.c-test.* || true
// RUN: XRAY_OPTIONS=patch_premain=true:verbosity=1:xray_mode=xray-basic %t \
// RUN: 2>&1 | FileCheck %s
diff --git a/test/xray/TestCases/Posix/profiling-multi-threaded.cc b/test/xray/TestCases/Posix/profiling-multi-threaded.cc
new file mode 100644
index 000000000..111b953eb
--- /dev/null
+++ b/test/xray/TestCases/Posix/profiling-multi-threaded.cc
@@ -0,0 +1,53 @@
+// Check that we can get a profile from a single-threaded application, on
+// demand through the XRay logging implementation API.
+//
+// FIXME: Make -fxray-modes=xray-profiling part of the default?
+// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=xray-profiling
+// RUN: %run %t
+//
+// UNSUPPORTED: target-is-mips64,target-is-mips64el
+
+#include "xray/xray_interface.h"
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <cstdio>
+#include <string>
+#include <thread>
+
+#define XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]]
+#define XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]]
+
+XRAY_ALWAYS_INSTRUMENT void f2() { return; }
+XRAY_ALWAYS_INSTRUMENT void f1() { f2(); }
+XRAY_ALWAYS_INSTRUMENT void f0() { f1(); }
+
+using namespace std;
+
+volatile int buffer_counter = 0;
+
+XRAY_NEVER_INSTRUMENT void process_buffer(const char *, XRayBuffer) {
+ // FIXME: Actually assert the contents of the buffer.
+ ++buffer_counter;
+}
+
+XRAY_ALWAYS_INSTRUMENT int main(int, char **) {
+ assert(__xray_log_select_mode("xray-profiling") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ assert(__xray_log_get_current_mode() != nullptr);
+ std::string current_mode = __xray_log_get_current_mode();
+ assert(current_mode == "xray-profiling");
+ assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
+ assert(__xray_log_init(0, 0, nullptr, 0) ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ std::thread t0([] { f0(); });
+ std::thread t1([] { f0(); });
+ f0();
+ t0.join();
+ t1.join();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ // We're running three threds, so we expect three buffers.
+ assert(buffer_counter == 3);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+}
diff --git a/test/xray/TestCases/Posix/profiling-single-threaded.cc b/test/xray/TestCases/Posix/profiling-single-threaded.cc
new file mode 100644
index 000000000..91d3efbe4
--- /dev/null
+++ b/test/xray/TestCases/Posix/profiling-single-threaded.cc
@@ -0,0 +1,58 @@
+// Check that we can get a profile from a single-threaded application, on
+// demand through the XRay logging implementation API.
+//
+// FIXME: Make -fxray-modes=xray-profiling part of the default?
+// RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=xray-profiling
+// RUN: %run %t
+//
+// UNSUPPORTED: target-is-mips64,target-is-mips64el
+
+#include "xray/xray_interface.h"
+#include "xray/xray_log_interface.h"
+#include <cassert>
+#include <cstdio>
+#include <string>
+
+[[clang::xray_always_instrument]] void f2() { return; }
+[[clang::xray_always_instrument]] void f1() { f2(); }
+[[clang::xray_always_instrument]] void f0() { f1(); }
+
+using namespace std;
+
+volatile int buffer_counter = 0;
+
+[[clang::xray_never_instrument]] void process_buffer(const char *, XRayBuffer) {
+ // FIXME: Actually assert the contents of the buffer.
+ ++buffer_counter;
+}
+
+[[clang::xray_always_instrument]] int main(int, char **) {
+ assert(__xray_log_select_mode("xray-profiling") ==
+ XRayLogRegisterStatus::XRAY_REGISTRATION_OK);
+ assert(__xray_log_get_current_mode() != nullptr);
+ std::string current_mode = __xray_log_get_current_mode();
+ assert(current_mode == "xray-profiling");
+ assert(__xray_patch() == XRayPatchingStatus::SUCCESS);
+ assert(__xray_log_init_mode("xray-profiling", "") ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ f0();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ f0();
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ assert(buffer_counter == 1);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+
+ // Let's reset the counter.
+ buffer_counter = 0;
+
+ assert(__xray_log_init_mode("xray-profiling", "") ==
+ XRayLogInitStatus::XRAY_LOG_INITIALIZED);
+ f0();
+ assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED);
+ f0();
+ assert(__xray_log_process_buffers(process_buffer) ==
+ XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+ assert(buffer_counter == 1);
+ assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED);
+}