Loading...
Searching...
No Matches
PotRegistry Class Reference

#include <PotRegistry.h>

Classes

struct  InstanceRecord
struct  TypeStats

Public Types

using Clock = std::chrono::system_clock
using TimePoint = Clock::time_point

Public Member Functions

void reset ()
uint64_t on_created (PotType t) noexcept
void on_destroyed (uint64_t id, PotType t, size_t force_calls, TimePoint created_at)
void on_force_call (PotType t) noexcept
size_t type_force_calls (PotType t) const noexcept
size_t total_force_calls () const noexcept
size_t type_alive (PotType t) const noexcept
void write_summary (const std::string &path="_potcalls.json") const

Static Public Member Functions

static PotRegistryget () noexcept
 Process-lifetime singleton.

Private Attributes

std::array< TypeStats, magic_enum::enum_count< PotType >()> m_type_stats {}
std::mutex m_records_mutex
std::vector< InstanceRecordm_records
std::atomic< uint64_t > m_next_id {1}

Detailed Description

Definition at line 24 of file PotRegistry.h.

Member Typedef Documentation

◆ Clock

using eonc::PotRegistry::Clock = std::chrono::system_clock

Definition at line 26 of file PotRegistry.h.

◆ TimePoint

using eonc::PotRegistry::TimePoint = Clock::time_point

Definition at line 27 of file PotRegistry.h.

Member Function Documentation

◆ get()

PotRegistry & eonc::PotRegistry::get ( )
staticnoexcept

Process-lifetime singleton.

The instance is allocated on the heap and never destroyed, so Potential destructors can still record teardown after C++ static destruction.

Definition at line 50 of file PotRegistry.cpp.

50 {
51 // Heap-allocated and never deleted. Potential destructors call
52 // on_destroyed, and those objects can outlive C++ static
53 // destructors (interpreter finalization, leaked shared_ptrs). A
54 // function-local static would already be destroyed on those paths,
55 // so on_destroyed would lock a destroyed mutex.
56 static PotRegistry *instance = new PotRegistry;
57 return *instance;
58}

◆ on_created()

uint64_t eonc::PotRegistry::on_created ( PotType t)
nodiscardnoexcept

Definition at line 71 of file PotRegistry.cpp.

71 {
72 auto idx = static_cast<size_t>(magic_enum::enum_index(t).value_or(0));
73 m_type_stats[idx].created.fetch_add(1, std::memory_order_relaxed);
74 m_type_stats[idx].alive.fetch_add(1, std::memory_order_relaxed);
75 return m_next_id.fetch_add(1, std::memory_order_relaxed);
76}
std::atomic< uint64_t > m_next_id
Definition PotRegistry.h:48
std::array< TypeStats, magic_enum::enum_count< PotType >()> m_type_stats
Definition PotRegistry.h:43

◆ on_destroyed()

void eonc::PotRegistry::on_destroyed ( uint64_t id,
PotType t,
size_t force_calls,
TimePoint created_at )

Definition at line 78 of file PotRegistry.cpp.

79 {
80 auto idx = static_cast<size_t>(magic_enum::enum_index(t).value_or(0));
81 m_type_stats[idx].alive.fetch_sub(1, std::memory_order_relaxed);
82
83 InstanceRecord rec{id, t, created_at, Clock::now(), force_calls};
84 std::lock_guard<std::mutex> lock(m_records_mutex);
85 m_records.push_back(rec);
86}
std::mutex m_records_mutex
Definition PotRegistry.h:45
std::vector< InstanceRecord > m_records
Definition PotRegistry.h:46

◆ on_force_call()

Definition at line 88 of file PotRegistry.cpp.

88 {
89 auto idx = static_cast<size_t>(magic_enum::enum_index(t).value_or(0));
90 m_type_stats[idx].force_calls.fetch_add(1, std::memory_order_relaxed);
91}

◆ reset()

Definition at line 60 of file PotRegistry.cpp.

60 {
61 for (auto &ts : m_type_stats) {
62 ts.force_calls.store(0, std::memory_order_relaxed);
63 ts.created.store(0, std::memory_order_relaxed);
64 ts.alive.store(0, std::memory_order_relaxed);
65 }
66 std::lock_guard<std::mutex> lock(m_records_mutex);
67 m_records.clear();
68 m_next_id.store(1, std::memory_order_relaxed);
69}

◆ total_force_calls()

size_t eonc::PotRegistry::total_force_calls ( ) const
nodiscardnoexcept

Definition at line 98 of file PotRegistry.cpp.

98 {
99 size_t total = 0;
100 for (const auto &ts : m_type_stats) {
101 total += ts.force_calls.load(std::memory_order_relaxed);
102 }
103 return total;
104}

◆ type_alive()

size_t eonc::PotRegistry::type_alive ( PotType t) const
nodiscardnoexcept

Definition at line 106 of file PotRegistry.cpp.

106 {
107 auto idx = static_cast<size_t>(magic_enum::enum_index(t).value_or(0));
108 return m_type_stats[idx].alive.load(std::memory_order_relaxed);
109}

◆ type_force_calls()

size_t eonc::PotRegistry::type_force_calls ( PotType t) const
nodiscardnoexcept

Definition at line 93 of file PotRegistry.cpp.

93 {
94 auto idx = static_cast<size_t>(magic_enum::enum_index(t).value_or(0));
95 return m_type_stats[idx].force_calls.load(std::memory_order_relaxed);
96}

◆ write_summary()

void eonc::PotRegistry::write_summary ( const std::string & path = "_potcalls.json") const

Definition at line 111 of file PotRegistry.cpp.

111 {
112 std::vector<InstanceRecord> snapshot;
113 {
114 std::lock_guard<std::mutex> lock(const_cast<std::mutex &>(m_records_mutex));
115 snapshot = m_records;
116 }
117
118 std::ofstream ofs(path);
119 if (!ofs.is_open())
120 return;
121
122 ofs << "[\n";
123 for (size_t i = 0; i < snapshot.size(); ++i) {
124 const auto &r = snapshot[i];
125 auto type_name = magic_enum::enum_name(r.type);
126 ofs << " {\n";
127 ofs << " \"id\": " << r.id << ",\n";
128 ofs << " \"type\": \"" << json_escape(type_name) << "\",\n";
129 ofs << " \"created_at\": \"" << format_timepoint(r.created_at)
130 << "\",\n";
131 ofs << " \"destroyed_at\": \"" << format_timepoint(r.destroyed_at)
132 << "\",\n";
133 ofs << " \"force_calls\": " << r.force_calls << "\n";
134 ofs << " }";
135 if (i + 1 < snapshot.size())
136 ofs << ',';
137 ofs << '\n';
138 }
139 ofs << "]\n";
140}

Member Data Documentation

◆ m_next_id

std::atomic<uint64_t> eonc::PotRegistry::m_next_id {1}
private

Definition at line 48 of file PotRegistry.h.

48{1};

◆ m_records

Definition at line 46 of file PotRegistry.h.

◆ m_records_mutex

Definition at line 45 of file PotRegistry.h.

◆ m_type_stats

std::array<TypeStats, magic_enum::enum_count<PotType>()> eonc::PotRegistry::m_type_stats {}
private

Definition at line 43 of file PotRegistry.h.

43{};

The documentation for this class was generated from the following files: