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