diff options
author | Dean Michael Berris <dberris@google.com> | 2018-06-12 03:29:39 +0000 |
---|---|---|
committer | Dean Michael Berris <dberris@google.com> | 2018-06-12 03:29:39 +0000 |
commit | da1b8bff539cef08140fb20b8e7ed0ae0c244df5 (patch) | |
tree | f09a7bcdd340024cbafb389b49a7f0cd6e1971dc /test/xray | |
parent | f8a3f1ef5dc8840cbf554cbec32373ca935172f1 (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.cc | 2 | ||||
-rw-r--r-- | test/xray/TestCases/Posix/profiling-multi-threaded.cc | 53 | ||||
-rw-r--r-- | test/xray/TestCases/Posix/profiling-single-threaded.cc | 58 |
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); +} |