mirror of
https://github.com/matrix-construct/construct
synced 2024-11-26 00:32:35 +01:00
ircd::prof: Add gadget for instruction profiling of a scope.
This commit is contained in:
parent
3196bbd26d
commit
0112d49f62
2 changed files with 82 additions and 0 deletions
|
@ -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.
|
||||
|
|
64
ircd/prof.cc
64
ircd/prof.cc
|
@ -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
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue