0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd::prof: Add gadget for instruction profiling of a scope.

This commit is contained in:
Jason Volk 2019-05-07 17:18:39 -07:00
parent 3196bbd26d
commit 0112d49f62
2 changed files with 82 additions and 0 deletions

View file

@ -20,6 +20,7 @@ namespace ircd::prof
struct system;
struct resource;
struct syscall_timer;
struct instructions;
enum dpl :uint8_t;
using group = std::vector<std::unique_ptr<event>>;
IRCD_OVERLOAD(sample)
@ -94,6 +95,23 @@ struct ircd::prof::vg::disable
~disable() noexcept;
};
/// Gadget for hardware profiling of instructions for a scope.
///
struct ircd::prof::instructions
{
prof::group group;
uint64_t val {0};
public:
const uint64_t &at() const;
const uint64_t &sample();
instructions() noexcept;
instructions(instructions &&) = delete;
instructions(const instructions &) = delete;
~instructions() noexcept;
};
/// This suite of devices is intended to figure out when a system call is
/// really slow or "blocking." The original use-case is for io_submit() in
/// fs::aio.

View file

@ -282,6 +282,70 @@ ircd::prof::vg::enabled()
return _enabled;
}
//
// instructions
//
ircd::prof::instructions::instructions()
noexcept
{
if(!create(this->group, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, true, false))
throw error
{
"Cannot sample instruction counter."
};
reset(this->group);
start(this->group);
}
ircd::prof::instructions::~instructions()
noexcept
{
}
const uint64_t &
ircd::prof::instructions::sample()
{
stop(this->group);
auto &leader
{
prof::leader(group)
};
thread_local char buf[1024];
const const_buffer read
{
buf, size_t(syscall(::read, int(leader.fd), buf, sizeof(buf)))
};
for_each(read, [this]
(const type &type, const uint64_t &val)
{
if(type.type_id == PERF_TYPE_HARDWARE)
if(type.counter == PERF_COUNT_HW_INSTRUCTIONS)
if(type.dpl == dpl::USER)
this->val += val;
});
const auto &ret
{
at()
};
start(this->group);
return ret;
}
const uint64_t &
ircd::prof::instructions::at()
const
{
return val;
}
//
// syscall_timer
//