Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix perfetto_counter_track string lifetime #28

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 56 additions & 10 deletions source/lib/omnitrace/library/perfetto.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@
PERFETTO_DEFINE_CATEGORIES(PERFETTO_CATEGORIES);
#endif

#include "library/debug.hpp"

#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

namespace omnitrace
{
#if defined(CUSTOM_DATA_SOURCE)
Expand All @@ -76,21 +85,21 @@ class CustomDataSource : public perfetto::DataSource<CustomDataSource>
{
// Use this callback to apply any custom configuration to your data source
// based on the TraceConfig in SetupArgs.
PRINT_HERE("%s", "setup");
OMNITRACE_PRINT_F("[CustomDataSource] setup\n");
}

void OnStart(const StartArgs&) override
{
// This notification can be used to initialize the GPU driver, enable
// counters, etc. StartArgs will contains the DataSourceDescriptor,
// which can be extended.
PRINT_HERE("%s", "start");
OMNITRACE_PRINT_F("[CustomDataSource] start\n");
}

void OnStop(const StopArgs&) override
{
// Undo any initialization done in OnStart.
PRINT_HERE("%s", "stop");
OMNITRACE_PRINT_F("[CustomDataSource] stop\n");
}

// Data sources can also have per-instance state.
Expand All @@ -104,7 +113,7 @@ template <typename Tp>
struct perfetto_counter_track
{
using track_map_t = std::map<uint32_t, std::vector<perfetto::CounterTrack>>;
using name_map_t = std::map<uint32_t, std::vector<std::string>>;
using name_map_t = std::map<uint32_t, std::vector<std::unique_ptr<std::string>>>;
using data_t = std::pair<name_map_t, track_map_t>;

static auto init() { (void) get_data(); }
Expand All @@ -123,20 +132,57 @@ struct perfetto_counter_track
return get_data().second.at(_idx).size();
}

static auto emplace(size_t _idx, const std::string& _v, const char* _units)
static auto emplace(size_t _idx, const std::string& _v, const char* _units = nullptr,
const char* _category = nullptr, int64_t _mult = 1,
bool _incr = false)
{
get_data().first[_idx].emplace_back(_v);
get_data().second[_idx].emplace_back(get_data().first[_idx].back().c_str(),
_units);
std::vector<std::tuple<std::string, const char*, bool>> _missing = {};
if(config::get_is_continuous_integration())
{
for(const auto& itr : get_data().first[_idx])
{
_missing.emplace_back(std::make_tuple(*itr, itr->c_str(), false));
}
}
auto& _name =
get_data().first[_idx].emplace_back(std::make_unique<std::string>(_v));
const char* _unit_name = (_units && strlen(_units) > 0) ? _units : nullptr;
get_data().second[_idx].emplace_back(perfetto::CounterTrack{ _name->c_str() }
.set_unit_name(_unit_name)
.set_category(_category)
.set_unit_multiplier(_mult)
.set_is_incremental(_incr));
if(config::get_is_continuous_integration())
{
for(auto& itr : _missing)
{
for(const auto& ditr : get_data().first.at(_idx))
{
if(*ditr == _v) continue;
const char* citr = std::get<1>(itr);
if(citr == ditr->c_str() && strcmp(citr, ditr->c_str()) == 0)
{
std::get<2>(itr) = true;
break;
}
}
if(!std::get<2>(itr))
{
OMNITRACE_THROW("perfetto_counter_track emplace method for '%s' "
"invalidated C-string '%s'\n",
_v.c_str(), std::get<0>(itr).c_str());
}
}
}
}

static auto& at(size_t _idx, size_t _n) { return get_data().second.at(_idx).at(_n); }

private:
static data_t& get_data()
{
static auto* _v = new data_t{};
return *_v;
static auto _v = data_t{};
return _v;
}
};
} // namespace omnitrace