| 1 | // Check that we can get a profile from a single-threaded application, on |
| 2 | // demand through the XRay logging implementation API. |
| 3 | // |
| 4 | // FIXME: Make -fxray-modes=xray-profiling part of the default? |
| 5 | // RUN: %clangxx_xray -std=c++11 %s -o %t -fxray-modes=xray-profiling |
| 6 | // RUN: rm -f xray-log.profiling-multi-* |
| 7 | // RUN: XRAY_OPTIONS=verbosity=1 \ |
| 8 | // RUN: XRAY_PROFILING_OPTIONS=no_flush=1 %run %t |
| 9 | // RUN: XRAY_OPTIONS=verbosity=1 %run %t |
| 10 | // RUN: PROFILES=`ls xray-log.profiling-multi-* | wc -l` |
| 11 | // RUN: [ $PROFILES -eq 1 ] |
| 12 | // RUN: rm -f xray-log.profiling-multi-* |
| 13 | // |
| 14 | // REQUIRES: built-in-llvm-tree |
| 15 | |
| 16 | #include "xray/xray_interface.h" |
| 17 | #include "xray/xray_log_interface.h" |
| 18 | #include <cassert> |
| 19 | #include <cstdio> |
| 20 | #include <string> |
| 21 | #include <thread> |
| 22 | |
| 23 | [[clang::xray_always_instrument]] void f2() { return; } |
| 24 | [[clang::xray_always_instrument]] void f1() { f2(); } |
| 25 | [[clang::xray_always_instrument]] void f0() { f1(); } |
| 26 | |
| 27 | using namespace std; |
| 28 | |
| 29 | volatile int buffer_counter = 0; |
| 30 | |
| 31 | [[clang::xray_never_instrument]] void process_buffer(const char *, XRayBuffer) { |
| 32 | // FIXME: Actually assert the contents of the buffer. |
| 33 | ++buffer_counter; |
| 34 | } |
| 35 | |
| 36 | [[clang::xray_always_instrument]] int main(int, char **) { |
| 37 | assert(__xray_log_select_mode("xray-profiling" ) == |
| 38 | XRayLogRegisterStatus::XRAY_REGISTRATION_OK); |
| 39 | assert(__xray_log_get_current_mode() != nullptr); |
| 40 | std::string current_mode = __xray_log_get_current_mode(); |
| 41 | assert(current_mode == "xray-profiling" ); |
| 42 | assert(__xray_patch() == XRayPatchingStatus::SUCCESS); |
| 43 | assert(__xray_log_init_mode("xray-profiling" , "" ) == |
| 44 | XRayLogInitStatus::XRAY_LOG_INITIALIZED); |
| 45 | std::thread t0([] { f0(); }); |
| 46 | std::thread t1([] { f0(); }); |
| 47 | f0(); |
| 48 | t0.join(); |
| 49 | t1.join(); |
| 50 | assert(__xray_log_finalize() == XRayLogInitStatus::XRAY_LOG_FINALIZED); |
| 51 | assert(__xray_log_process_buffers(process_buffer) == |
| 52 | XRayLogFlushStatus::XRAY_LOG_FLUSHED); |
| 53 | // We're running three threads, so we expect four buffers (including the file |
| 54 | // header buffer). |
| 55 | assert(buffer_counter == 4); |
| 56 | assert(__xray_log_flushLog() == XRayLogFlushStatus::XRAY_LOG_FLUSHED); |
| 57 | } |
| 58 | |