Remove the roctx range message stack

The range message stack is mirrored in case ranges are pushed or popped
while tracing is stopped (by the tracer tool?). When a stop event is
reported, the tracer tool emits RangePop events by unwinding the stack,
then when the start event is reported, it emits RangePush events again
by unwinding the stack. The issue is that the RangePush events should
be emitted in reverse order.

For example:

RangePush(M1); RangePush(M2); \
  TracerStop; RangePop; RangePop; \
...; \
  TracerStart; RangePush(M2); RangePush(M1); \ <- In the wrong order
RangePop; RangePop;

It could be fixed by reversing the stack in RangeStackIterate but is it
worth it? The roctx range markers are supposed to be unintrusive so that
they can be left in the application even when it isn't being traced.

Simplifying the roctx API and reducing its added latency by removing
the range message stack mirroring seems like the better choise.

TODO: A future change should make roctx events immune to tracer start
and tracer stop requests. Or simply remove roctracer_start/stop.

Change-Id: Ie4d76afb5ce8d263848dcf1b599af394db56ddab
This commit is contained in:
Laurent Morichetti
2022-05-06 14:01:27 -07:00
parent 713db1fce5
commit 3d0198c395
4 changed files with 17 additions and 84 deletions
+2 -5
View File
@@ -278,19 +278,16 @@ class RocTxApi {
public:
typedef BaseLoader<RocTxApi> Loader;
typedef decltype(RegisterApiCallback) RegisterApiCallback_t;
typedef decltype(RemoveApiCallback) RemoveApiCallback_t;
typedef decltype(RangeStackIterate) RangeStackIterate_t;
typedef bool(RegisterApiCallback_t)(uint32_t op, void* callback, void* arg);
typedef bool(RemoveApiCallback_t)(uint32_t op);
RegisterApiCallback_t* RegisterApiCallback;
RemoveApiCallback_t* RemoveApiCallback;
RangeStackIterate_t* RangeStackIterate;
protected:
void init(Loader* loader) {
RegisterApiCallback = loader->GetFun<RegisterApiCallback_t>("RegisterApiCallback");
RemoveApiCallback = loader->GetFun<RemoveApiCallback_t>("RemoveApiCallback");
RangeStackIterate = loader->GetFun<RangeStackIterate_t>("RangeStackIterate");
}
};
+6 -36
View File
@@ -22,11 +22,6 @@
#include "inc/roctracer_roctx.h"
#include <cassert>
#include <cstring>
#include <unordered_map>
#include <mutex>
#include <stack>
#include <string>
#include "inc/ext/prof_protocol.h"
#include "core/callback_table.h"
@@ -63,14 +58,7 @@ typedef enum {
namespace {
roctracer::CallbackTable<ROCTX_API_ID_NUMBER> callbacks;
std::unordered_map<uint32_t, std::stack<std::string>> message_stack_map;
std::mutex message_stack_mutex;
thread_local auto& message_stack = []() -> decltype(message_stack_map)::mapped_type& {
const auto tid = syscall(__NR_gettid);
std::lock_guard lock(message_stack_mutex);
return message_stack_map[tid];
}();
thread_local int range_level(0);
} // namespace
@@ -106,8 +94,7 @@ PUBLIC_API int roctxRangePushA(const char* message) {
api_callback_arg);
}
message_stack.emplace(message);
return message_stack.size() - 1;
return range_level++;
API_METHOD_CATCH(-1);
}
@@ -120,12 +107,8 @@ PUBLIC_API int roctxRangePop() {
api_callback_arg);
}
if (message_stack.empty()) {
EXC_RAISING(ROCTX_STATUS_ERROR, "Pop from empty stack!");
}
message_stack.pop();
return message_stack.size();
if (range_level == 0) EXC_RAISING(ROCTX_STATUS_ERROR, "Pop from empty stack!");
return --range_level;
API_METHOD_CATCH(-1)
}
@@ -157,26 +140,13 @@ PUBLIC_API void roctxRangeStop(roctx_range_id_t rangeId) {
API_METHOD_SUFFIX_NRET
}
PUBLIC_API void RangeStackIterate(roctx_range_iterate_cb_t callback, void* arg) {
std::lock_guard lock(message_stack_mutex);
for (auto&& [tid, message_stack] : message_stack_map) {
// Since we can't iterate a std::stack, we must first make a copy and then unwind it.
for (auto stack_copy = message_stack; !stack_copy.empty(); stack_copy.pop()) {
roctx_range_data_t data{};
data.message = stack_copy.top().c_str();
data.tid = tid;
callback(&data, arg);
}
}
}
PUBLIC_API bool RegisterApiCallback(uint32_t op, void* callback, void* arg) {
extern "C" PUBLIC_API bool RegisterApiCallback(uint32_t op, void* callback, void* arg) {
if (op >= ROCTX_API_ID_NUMBER) return false;
callbacks.Set(op, reinterpret_cast<activity_rtapi_callback_t>(callback), arg);
return true;
}
PUBLIC_API bool RemoveApiCallback(uint32_t op) {
extern "C" PUBLIC_API bool RemoveApiCallback(uint32_t op) {
if (op >= ROCTX_API_ID_NUMBER) return false;
callbacks.Set(op, nullptr, nullptr);
return true;