blob: a9a844a8f3c2fce6e83642561c956dafb5a22263 [file] [log] [blame]
//===- fdrmode-bench.cc - XRay Instrumentation Benchmarks ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Define benchmarks for measuring the cost of XRay instrumentation when using
// flight data recorder mode.
//
//===----------------------------------------------------------------------===//
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include "benchmark/benchmark.h"
#include "xray/xray_interface.h"
#include "xray/xray_log_interface.h"
namespace {
// This needs to be a global value so that the compiler doesn't end up writing
// to data on the stack. We also mark it volatile to preserve all the loads and
// stores performed on this variable.
volatile int val = 0;
__xray::FDRLoggingOptions Options;
} // namespace
// We define a multi-threaded benchmark which measures the overall costs
// introduced by the XRay handlers upstream. This will exercise a tight loop
// calling a single function that practically does nothing.
[[clang::xray_always_instrument]] __attribute__((noinline)) __attribute__((weak)) int
EmptyFunction() {
return 0;
}
volatile bool log_initialized = false;
// Force installation of the FDR logging implementation upstream, with the
// caveat that we're writing the log out to /dev/null.
[[clang::xray_never_instrument]] void SetUpXRayFDRMultiThreaded(
benchmark::State& state) {
if (!log_initialized) {
Options.ReportErrors = true;
Options.Fd = open("/dev/null", O_WRONLY);
assert((Options.Fd != -1) && "Cannot open /dev/null!");
__xray_log_init(getpagesize(), 1 << 16, &Options,
sizeof(__xray::FDRLoggingOptions));
__xray_remove_customevent_handler();
__xray_patch();
log_initialized = true;
}
}
[[clang::xray_never_instrument]] void TearDownXRayFDRMultiThreaded(
benchmark::State& state) {
if (log_initialized) {
log_initialized = false;
__xray_log_finalize();
__xray_log_flushLog();
__xray_unpatch();
}
}
[[clang::xray_never_instrument]] static void BM_XRayFDRMultiThreaded(
benchmark::State& state) {
if (state.thread_index == 0) {
SetUpXRayFDRMultiThreaded(state);
}
for (auto _ : state) {
val = EmptyFunction();
benchmark::DoNotOptimize(val);
}
if (state.thread_index == 0) {
TearDownXRayFDRMultiThreaded(state);
}
}
BENCHMARK(BM_XRayFDRMultiThreaded)
->ThreadRange(1, 32); // Number of threads
BENCHMARK_MAIN();