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 PerfDescriptorsHolder PerfEventsCounters::thread_events_descriptors_holder{};
thread_local bool PerfEventsCounters::thread_events_descriptors_opened = false; 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::perf_unavailability_logged = false;
std::atomic<bool> PerfEventsCounters::particular_events_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) void PerfEventsCounters::initializeProfileEvents(PerfEventsCounters & counters)
{ {
if (current_thread_counters == &counters) if (current_thread_counters_id.has_value())
return;
if (current_thread_counters != nullptr)
{ {
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; return;
} }
@ -282,12 +282,12 @@ void PerfEventsCounters::initializeProfileEvents(PerfEventsCounters & counters)
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); 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) void PerfEventsCounters::finalizeProfileEvents(PerfEventsCounters & counters, ProfileEvents::Counters & profile_events)
{ {
if (current_thread_counters != &counters) if (current_thread_counters_id != counters.id)
return; return;
if (!thread_events_descriptors_opened) if (!thread_events_descriptors_opened)
return; return;
@ -330,9 +330,11 @@ void PerfEventsCounters::finalizeProfileEvents(PerfEventsCounters & counters, Pr
LOG_WARNING(getLogger(), "Can't reset perf event with file descriptor: " << fd); 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() PerfDescriptorsHolder::PerfDescriptorsHolder()
{ {
for (int & descriptor : descriptors) for (int & descriptor : descriptors)

View File

@ -182,6 +182,9 @@ struct PerfDescriptorsHolder;
struct PerfEventsCounters 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) // 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/ // https://lwn.net/Articles/696234/
// -1: Allow use of (almost) all events by all users // -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); static void finalizeProfileEvents(PerfEventsCounters & counters, ProfileEvents::Counters & profile_events);
PerfEventsCounters();
private: private:
static std::atomic<Id> counters_id;
// used to write information about perf unavailability only once for all threads // used to write information about perf unavailability only once for all threads
static std::atomic<bool> perf_unavailability_logged; static std::atomic<bool> perf_unavailability_logged;
// used to write information about particular perf events unavailability only once for all threads // 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 PerfDescriptorsHolder thread_events_descriptors_holder;
static thread_local bool thread_events_descriptors_opened; 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 // temp array just to not create it each time event processing finishes
PerfEventValue raw_event_values[NUMBER_OF_RAW_EVENTS]{}; PerfEventValue raw_event_values[NUMBER_OF_RAW_EVENTS]{};