Stop all client contexts prior to finalization (#721)

* Stop all client contexts prior to finalization

* Update lib/common/container/static_vector.hpp

- improve emplace_back for non-{move,copy}-assignable object

* Update samples/intercept_table/client.cpp

- improve robustness against static object destruction

* Update lib/rocprofiler-sdk/context/context.cpp

- change storage of registered context array
  - stable_vector of optional contexts
  - common::static_object wrapper around stable_vector

* Update samples/intercept_table/client.cpp

- use variable template for underlying function pointer
Этот коммит содержится в:
Jonathan R. Madsen
2024-04-02 03:05:11 -05:00
коммит произвёл GitHub
родитель e3c7eed7c0
Коммит 939e23e9d1
9 изменённых файлов: 115 добавлений и 63 удалений
+26 -15
Просмотреть файл
@@ -76,8 +76,8 @@ using callback_kind_operation_names_t =
std::map<rocprofiler_callback_tracing_kind_t, std::map<uint32_t, const char*>>;
using wrap_count_t = std::pair<source_location, size_t>;
rocprofiler_client_id_t* client_id = nullptr;
std::map<size_t, wrap_count_t> client_wrap_data = {};
rocprofiler_client_id_t* client_id = nullptr;
auto* client_wrap_data = new std::map<size_t, wrap_count_t>{};
void
print_call_stack(const call_stack_t& _call_stack)
@@ -113,7 +113,7 @@ print_call_stack(const call_stack_t& _call_stack)
{
*ofs << std::left << std::setw(2) << ++n << "/" << std::setw(2) << _call_stack.size()
<< " [" << common::fs::path{itr.file}.filename() << ":" << itr.line << "] "
<< std::setw(20) << itr.function;
<< std::setw(41) << itr.function;
if(!itr.context.empty()) *ofs << " :: " << itr.context;
*ofs << "\n";
}
@@ -131,7 +131,7 @@ tool_fini(void* tool_data)
auto* _call_stack = static_cast<call_stack_t*>(tool_data);
size_t wrapped_count = 0;
for(const auto& itr : client_wrap_data)
for(const auto& itr : *client_wrap_data)
{
auto src_loc = itr.second.first;
src_loc.context += "call_count=" + std::to_string(itr.second.second);
@@ -144,6 +144,7 @@ tool_fini(void* tool_data)
print_call_stack(*_call_stack);
delete _call_stack;
delete client_wrap_data;
if(wrapped_count == 0)
{
@@ -151,22 +152,32 @@ tool_fini(void* tool_data)
}
}
template <size_t Idx, typename RetT, typename... Args>
RetT (*underlying_function)(Args...) = nullptr;
template <size_t Idx, typename RetT, typename... Args>
RetT
get_wrapper_function(Args... args)
{
if(client_wrap_data->at(Idx).second == 0)
std::clog << "First invocation of wrapped function: '"
<< client_wrap_data->at(Idx).first.function << "'...\n"
<< std::flush;
client_wrap_data->at(Idx).second += 1;
if(underlying_function<Idx, RetT, Args...>)
return underlying_function<Idx, RetT, Args...>(args...);
if constexpr(!std::is_void<RetT>::value) return RetT{};
}
template <size_t Idx, typename RetT, typename... Args>
auto
generate_wrapper(const char* name, RetT (*func)(Args...))
{
using functor_type = RetT (*)(Args...);
client_wrap_data->emplace(Idx, wrap_count_t{source_location{name, __FILE__, __LINE__, ""}, 0});
client_wrap_data.emplace(Idx, wrap_count_t{source_location{name, __FILE__, __LINE__, ""}, 0});
static functor_type underlying_func = func;
static functor_type wrapped_func = [](Args... args) -> RetT {
client_wrap_data.at(Idx).second += 1;
if(underlying_func) return underlying_func(args...);
if constexpr(!std::is_void<RetT>::value) return RetT{};
};
return wrapped_func;
underlying_function<Idx, RetT, Args...> = func;
return &get_wrapper_function<Idx, RetT, Args...>;
}
#define GENERATE_WRAPPER(TABLE, FUNC) \