mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 18:22:50 +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 system;
|
||||||
struct resource;
|
struct resource;
|
||||||
struct syscall_timer;
|
struct syscall_timer;
|
||||||
|
struct instructions;
|
||||||
enum dpl :uint8_t;
|
enum dpl :uint8_t;
|
||||||
using group = std::vector<std::unique_ptr<event>>;
|
using group = std::vector<std::unique_ptr<event>>;
|
||||||
IRCD_OVERLOAD(sample)
|
IRCD_OVERLOAD(sample)
|
||||||
|
@ -94,6 +95,23 @@ struct ircd::prof::vg::disable
|
||||||
~disable() noexcept;
|
~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
|
/// 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
|
/// really slow or "blocking." The original use-case is for io_submit() in
|
||||||
/// fs::aio.
|
/// fs::aio.
|
||||||
|
|
64
ircd/prof.cc
64
ircd/prof.cc
|
@ -282,6 +282,70 @@ ircd::prof::vg::enabled()
|
||||||
return _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
|
// syscall_timer
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue