Skip to content

Commit

Permalink
[Loader] Fix xpti finalization order
Browse files Browse the repository at this point in the history
Global xptiContext was beeing (sometimes) destroyed before the
tracing context (as both were global variables, their order of
destruction was not guaranteed). This resulted in lost
notifications as xptiFinalize was being called after xptiFrameworkFinalize.

Fix this by creating a global shared_ptr to the xptiContext.
Bump the refcount of that pointer every time a context is created
and decrease when it is destroyed to make sure that xptiFrameworkInitialize()
is not beeing called before the last context is destroyed.
  • Loading branch information
igchor committed Aug 21, 2024
1 parent 336e37b commit 7075a0a
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 43 deletions.
51 changes: 8 additions & 43 deletions source/loader/layers/tracing/ur_tracing_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,19 @@ constexpr auto STREAM_VER_MINOR = UR_MINOR_VERSION(UR_API_VERSION_CURRENT);
// Unfortunately this doesn't match the semantics of XPTI, which can be initialized
// and finalized exactly once. To workaround this, XPTI is globally initialized on
// first use and finalized in the destructor.
class XptiContext {
XptiContext() {
xptiFrameworkInitialize();
inited = true;
}

~XptiContext() {
xptiFrameworkFinalize();
inited = false;
}

// Accessing this after destruction is technically UB, but if we get there,
// it means something is calling UR after it has been destroyed at program
// exit.
std::atomic_bool inited;

public:
static bool running() {
static XptiContext context;
return context.inited;
}
struct XptiContextManager {
XptiContextManager() { xptiFrameworkInitialize(); }
~XptiContextManager() { xptiFrameworkFinalize(); }
};

static std::shared_ptr<XptiContextManager> xptiContextManagerGlobal = [] {
return std::make_shared<XptiContextManager>();
}();
static thread_local xpti_td *activeEvent;

///////////////////////////////////////////////////////////////////////////////
context_t::context_t() : logger(logger::create_logger("tracing", true, true)) {
if (!XptiContext::running()) {
return;
}
this->xptiContextManager = xptiContextManagerGlobal;

call_stream_id = xptiRegisterStream(CALL_STREAM_NAME);
std::ostringstream streamv;
Expand All @@ -69,20 +52,12 @@ context_t::context_t() : logger(logger::create_logger("tracing", true, true)) {

void context_t::notify(uint16_t trace_type, uint32_t id, const char *name,
void *args, ur_result_t *resultp, uint64_t instance) {
if (!XptiContext::running()) {
return;
}

xpti::function_with_args_t payload{id, name, args, resultp, nullptr};
xptiNotifySubscribers(call_stream_id, trace_type, nullptr, activeEvent,
instance, &payload);
}

uint64_t context_t::notify_begin(uint32_t id, const char *name, void *args) {
if (!XptiContext::running()) {
return 0;
}

if (auto loc = codelocData.get_codeloc()) {
xpti::payload_t payload =
xpti::payload_t(loc->functionName, loc->sourceFile, loc->lineNumber,
Expand All @@ -101,20 +76,10 @@ uint64_t context_t::notify_begin(uint32_t id, const char *name, void *args) {

void context_t::notify_end(uint32_t id, const char *name, void *args,
ur_result_t *resultp, uint64_t instance) {
if (!XptiContext::running()) {
return;
}

notify((uint16_t)xpti::trace_point_type_t::function_with_args_end, id, name,
args, resultp, instance);
}

///////////////////////////////////////////////////////////////////////////////
context_t::~context_t() {
if (!XptiContext::running()) {
return;
}

xptiFinalize(CALL_STREAM_NAME);
}
context_t::~context_t() { xptiFinalize(CALL_STREAM_NAME); }
} // namespace ur_tracing_layer
4 changes: 4 additions & 0 deletions source/loader/layers/tracing/ur_tracing_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#define TRACING_COMP_NAME "tracing layer"

namespace ur_tracing_layer {
struct XptiContextManager;

///////////////////////////////////////////////////////////////////////////////
class __urdlllocal context_t : public proxy_layer_context_t,
public AtomicSingleton<context_t> {
Expand All @@ -47,6 +49,8 @@ class __urdlllocal context_t : public proxy_layer_context_t,
uint8_t call_stream_id;

inline static const std::string name = "UR_LAYER_TRACING";

std::shared_ptr<XptiContextManager> xptiContextManager;
};

context_t *getContext();
Expand Down

0 comments on commit 7075a0a

Please sign in to comment.