UInt64 numbers to track active counters instead of memory addresses

This commit is contained in:
Andrey Skobtsov 2020-05-19 01:13:55 +03:00
parent 979b357c05
commit e46cabe1d8
2 changed files with 18 additions and 9 deletions

View File

@ -166,8 +166,9 @@ const PerfEventInfo PerfEventsCounters::raw_events_info[] = {
thread_local PerfDescriptorsHolder PerfEventsCounters::thread_events_descriptors_holder{};
thread_local bool PerfEventsCounters::thread_events_descriptors_opened = false;
thread_local PerfEventsCounters * PerfEventsCounters::current_thread_counters = nullptr;
thread_local std::optional<PerfEventsCounters::Id> PerfEventsCounters::current_thread_counters_id = std::nullopt;
std::atomic<PerfEventsCounters::Id> PerfEventsCounters::counters_id = 0;
std::atomic<bool> PerfEventsCounters::perf_unavailability_logged = false;
std::atomic<bool> PerfEventsCounters::particular_events_unavailability_logged = false;
@ -262,11 +263,10 @@ bool PerfEventsCounters::initializeThreadLocalEvents(PerfEventsCounters & counte
void PerfEventsCounters::initializeProfileEvents(PerfEventsCounters & counters)
{
if (current_thread_counters == &counters)
return;
if (current_thread_counters != nullptr)
if (current_thread_counters_id.has_value())
{
LOG_WARNING(getLogger(), "Only one instance of `PerfEventsCounters` can be used on the thread");
if (current_thread_counters_id != counters.id)
LOG_WARNING(getLogger(), "Only one instance of `PerfEventsCounters` can be used on the thread");
return;
}
@ -282,12 +282,12 @@ void PerfEventsCounters::initializeProfileEvents(PerfEventsCounters & counters)
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
}
current_thread_counters = &counters;
current_thread_counters_id = counters.id;
}
void PerfEventsCounters::finalizeProfileEvents(PerfEventsCounters & counters, ProfileEvents::Counters & profile_events)
{
if (current_thread_counters != &counters)
if (current_thread_counters_id != counters.id)
return;
if (!thread_events_descriptors_opened)
return;
@ -330,9 +330,11 @@ void PerfEventsCounters::finalizeProfileEvents(PerfEventsCounters & counters, Pr
LOG_WARNING(getLogger(), "Can't reset perf event with file descriptor: " << fd);
}
current_thread_counters = nullptr;
current_thread_counters_id.reset();
}
PerfEventsCounters::PerfEventsCounters(): id(counters_id++) {}
PerfDescriptorsHolder::PerfDescriptorsHolder()
{
for (int & descriptor : descriptors)

View File

@ -182,6 +182,9 @@ struct PerfDescriptorsHolder;
struct PerfEventsCounters
{
// must be unsigned to not cause undefined behaviour on increment
typedef UInt64 Id;
// cat /proc/sys/kernel/perf_event_paranoid - if perf_event_paranoid is set to 3, all calls to `perf_event_open` are rejected (even for the current process)
// https://lwn.net/Articles/696234/
// -1: Allow use of (almost) all events by all users
@ -203,7 +206,10 @@ struct PerfEventsCounters
static void finalizeProfileEvents(PerfEventsCounters & counters, ProfileEvents::Counters & profile_events);
PerfEventsCounters();
private:
static std::atomic<Id> counters_id;
// used to write information about perf unavailability only once for all threads
static std::atomic<bool> perf_unavailability_logged;
// used to write information about particular perf events unavailability only once for all threads
@ -211,8 +217,9 @@ private:
static thread_local PerfDescriptorsHolder thread_events_descriptors_holder;
static thread_local bool thread_events_descriptors_opened;
static thread_local PerfEventsCounters * current_thread_counters;
static thread_local std::optional<PerfEventsCounters::Id> current_thread_counters_id;
Id id;
// temp array just to not create it each time event processing finishes
PerfEventValue raw_event_values[NUMBER_OF_RAW_EVENTS]{};