2022-05-17 13:54:40 +00:00
|
|
|
// Copyright 2019-2022, Collabora, Ltd.
|
2019-08-31 11:46:25 +00:00
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Variable tracking code.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup aux_util
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "util/u_var.h"
|
|
|
|
#include "util/u_time.h"
|
|
|
|
#include "util/u_misc.h"
|
|
|
|
#include "util/u_debug.h"
|
|
|
|
#include "util/u_device.h"
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <sstream>
|
|
|
|
#include <vector>
|
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
namespace xrt::auxiliary::util {
|
|
|
|
|
|
|
|
|
2019-08-31 11:46:25 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Enums, Classes and Defines.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
/*!
|
|
|
|
* Simple container for the variable information.
|
|
|
|
*/
|
2019-08-31 11:46:25 +00:00
|
|
|
class Var
|
|
|
|
{
|
|
|
|
public:
|
2020-09-11 14:09:40 +00:00
|
|
|
struct u_var_info info = {};
|
2019-08-31 11:46:25 +00:00
|
|
|
};
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
/*!
|
|
|
|
* Object that has a series of tracked variables.
|
|
|
|
*/
|
2019-08-31 11:46:25 +00:00
|
|
|
class Obj
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::string name = {};
|
|
|
|
std::vector<Var> vars = {};
|
|
|
|
};
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
/*!
|
|
|
|
* Object that has a series of tracked variables.
|
|
|
|
*/
|
2019-08-31 11:46:25 +00:00
|
|
|
class Tracker
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::unordered_map<std::string, size_t> counters = {};
|
|
|
|
std::unordered_map<ptrdiff_t, Obj> map = {};
|
2022-07-13 17:21:51 +00:00
|
|
|
bool on = false;
|
|
|
|
bool tested = false;
|
2019-08-31 11:46:25 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
int
|
2019-12-03 16:20:36 +00:00
|
|
|
getNumber(const std::string &name)
|
2019-08-31 11:46:25 +00:00
|
|
|
{
|
|
|
|
auto s = counters.find(name);
|
2021-03-26 22:04:20 +00:00
|
|
|
int count = int(s != counters.end() ? s->second : 0) + 1;
|
2019-08-31 11:46:25 +00:00
|
|
|
counters[name] = count;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
/*!
|
|
|
|
* Global variable tracking state.
|
|
|
|
*/
|
|
|
|
static class Tracker gTracker;
|
2019-08-31 11:46:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Helper functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static bool
|
|
|
|
get_on()
|
|
|
|
{
|
2022-05-17 13:54:40 +00:00
|
|
|
if (gTracker.tested) {
|
|
|
|
return gTracker.on;
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
2022-05-17 13:54:40 +00:00
|
|
|
gTracker.on = debug_get_bool_option("XRT_TRACK_VARIABLES", false);
|
|
|
|
gTracker.tested = true;
|
2019-08-31 11:46:25 +00:00
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
return gTracker.on;
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_var(void *root, void *ptr, u_var_kind kind, const char *c_name)
|
|
|
|
{
|
2022-05-17 13:54:40 +00:00
|
|
|
auto s = gTracker.map.find((ptrdiff_t)root);
|
|
|
|
if (s == gTracker.map.end()) {
|
2019-08-31 11:46:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Var var;
|
2021-03-26 22:04:20 +00:00
|
|
|
snprintf(var.info.name, U_VAR_NAME_STRING_SIZE, "%s", c_name);
|
2020-09-11 14:09:40 +00:00
|
|
|
var.info.kind = kind;
|
|
|
|
var.info.ptr = ptr;
|
2019-08-31 11:46:25 +00:00
|
|
|
|
|
|
|
s->second.vars.push_back(var);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Exported functions.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
u_var_force_on(void)
|
|
|
|
{
|
2022-05-17 13:54:40 +00:00
|
|
|
gTracker.on = true;
|
|
|
|
gTracker.tested = true;
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
u_var_add_root(void *root, const char *c_name, bool number)
|
|
|
|
{
|
|
|
|
if (!get_on()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto name = std::string(c_name);
|
|
|
|
|
|
|
|
if (number) {
|
2022-05-17 13:54:40 +00:00
|
|
|
int count = gTracker.getNumber(name);
|
2019-08-31 11:46:25 +00:00
|
|
|
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << name << " #" << count;
|
|
|
|
name = ss.str();
|
|
|
|
}
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
auto &obj = gTracker.map[(ptrdiff_t)root] = Obj();
|
2019-08-31 11:46:25 +00:00
|
|
|
obj.name = name;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
u_var_remove_root(void *root)
|
|
|
|
{
|
|
|
|
if (!get_on()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
auto s = gTracker.map.find((ptrdiff_t)root);
|
|
|
|
if (s == gTracker.map.end()) {
|
2019-08-31 11:46:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
gTracker.map.erase(s);
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
2021-01-14 14:13:48 +00:00
|
|
|
u_var_visit(u_var_root_cb enter_cb, u_var_root_cb exit_cb, u_var_elm_cb elem_cb, void *priv)
|
2019-08-31 11:46:25 +00:00
|
|
|
{
|
|
|
|
if (!get_on()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<Obj *> tmp;
|
2022-05-17 13:54:40 +00:00
|
|
|
tmp.reserve(gTracker.map.size());
|
2019-08-31 11:46:25 +00:00
|
|
|
|
2022-05-17 13:54:40 +00:00
|
|
|
for (auto &n : gTracker.map) {
|
2019-08-31 11:46:25 +00:00
|
|
|
tmp.push_back(&n.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Obj *obj : tmp) {
|
2019-12-03 16:20:36 +00:00
|
|
|
enter_cb(obj->name.c_str(), priv);
|
2019-08-31 11:46:25 +00:00
|
|
|
|
|
|
|
for (auto &var : obj->vars) {
|
2020-09-11 14:09:40 +00:00
|
|
|
elem_cb(&var.info, priv);
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
|
|
|
|
2019-12-03 16:20:36 +00:00
|
|
|
exit_cb(obj->name.c_str(), priv);
|
2019-08-31 11:46:25 +00:00
|
|
|
}
|
|
|
|
}
|
2019-09-06 17:10:08 +00:00
|
|
|
|
2021-01-14 14:13:48 +00:00
|
|
|
#define ADD_FUNC(SUFFIX, TYPE, ENUM) \
|
|
|
|
extern "C" void u_var_add_##SUFFIX(void *obj, TYPE *ptr, const char *c_name) \
|
|
|
|
{ \
|
|
|
|
if (!get_on()) { \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
add_var(obj, (void *)ptr, U_VAR_KIND_##ENUM, c_name); \
|
2019-09-06 17:10:08 +00:00
|
|
|
}
|
|
|
|
|
2020-01-25 14:53:26 +00:00
|
|
|
U_VAR_ADD_FUNCS()
|
2019-09-06 17:10:08 +00:00
|
|
|
|
|
|
|
#undef ADD_FUNC
|
2022-05-17 13:54:40 +00:00
|
|
|
|
|
|
|
} // namespace xrt::auxiliary::util
|