1 // RUN: %clangxx_xray -g -std=c++11 %s -o %t 2 // RUN: rm xray-log.fdr-reinit* || true 3 // RUN: XRAY_OPTIONS="verbosity=1" %run %t 4 // RUN: rm xray-log.fdr-reinit* || true 5 #include "xray/xray_log_interface.h" 6 #include <atomic> 7 #include <cassert> 8 #include <cstddef> 9 #include <thread> 10 11 volatile uint64_t var = 0; 12 13 std::atomic_flag keep_going = ATOMIC_FLAG_INIT; 14 15 [[clang::xray_always_instrument]] void __attribute__((noinline)) func() { 16 ++var; 17 } 18 19 int main(int argc, char *argv[]) { 20 // Start a thread that will just keep calling the function, to spam calls to 21 // the function call handler. 22 keep_going.test_and_set(std::memory_order_acquire); 23 std::thread t([] { 24 while (keep_going.test_and_set(std::memory_order_acquire)) 25 func(); 26 }); 27 28 static constexpr char kConfig[] = 29 "buffer_size=1024:buffer_max=10:no_file_flush=true"; 30 31 // Then we initialize the FDR mode implementation. 32 assert(__xray_log_select_mode("xray-fdr") == 33 XRayLogRegisterStatus::XRAY_REGISTRATION_OK); 34 auto init_status = __xray_log_init_mode("xray-fdr", kConfig); 35 assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED); 36 37 // Now we patch the instrumentation points. 38 __xray_patch(); 39 40 // Spin for a bit, calling func() enough times. 41 for (auto i = 0; i < 1 << 20; ++i) 42 func(); 43 44 // Then immediately finalize the implementation. 45 auto finalize_status = __xray_log_finalize(); 46 assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED); 47 48 // Once we're here, we should then flush. 49 auto flush_status = __xray_log_flushLog(); 50 assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED); 51 52 for (auto trial = 0; trial < 3; trial++) { 53 // Without doing anything else, we should re-initialize. 54 init_status = __xray_log_init_mode("xray-fdr", kConfig); 55 assert(init_status == XRayLogInitStatus::XRAY_LOG_INITIALIZED); 56 57 // Then we spin for a bit again calling func() enough times. 58 for (auto i = 0; i < 1 << 20; ++i) 59 func(); 60 61 // Then immediately finalize the implementation. 62 finalize_status = __xray_log_finalize(); 63 assert(finalize_status == XRayLogInitStatus::XRAY_LOG_FINALIZED); 64 65 // Once we're here, we should then flush. 66 flush_status = __xray_log_flushLog(); 67 assert(flush_status == XRayLogFlushStatus::XRAY_LOG_FLUSHED); 68 } 69 70 // Finally, we should signal the sibling thread to stop. 71 keep_going.clear(std::memory_order_release); 72 73 // Then join. 74 t.join(); 75 } 76