eOn client
Long-timescale dynamics: aKMC, NEB, parallel replica
☾
Toggle main menu visibility
Loading...
Searching...
No Matches
PotRegistry.cpp
Go to the documentation of this file.
1
/*
2
** This file is part of eOn.
3
**
4
** SPDX-License-Identifier: BSD-3-Clause
5
**
6
** Copyright (c) 2010--present, eOn Development Team
7
** All rights reserved.
8
**
9
** Repo:
10
** https://github.com/TheochemUI/eOn
11
*/
12
#include "
eon/PotRegistry.h
"
13
#include <fstream>
14
#include <iomanip>
15
#include <sstream>
16
17
namespace
eonc
{
18
19
namespace
{
20
std::string format_timepoint(
PotRegistry::TimePoint
tp) {
21
auto
time_t_val = PotRegistry::Clock::to_time_t(tp);
22
auto
us = std::chrono::duration_cast<std::chrono::microseconds>(
23
tp.time_since_epoch()) %
24
std::chrono::seconds{1};
25
std::tm tm_buf{};
26
#ifdef _WIN32
27
localtime_s(&tm_buf, &time_t_val);
28
#else
29
localtime_r(&time_t_val, &tm_buf);
30
#endif
31
std::ostringstream oss;
32
oss << std::put_time(&tm_buf,
"%Y-%m-%dT%H:%M:%S"
);
33
oss <<
'.'
<< std::setfill(
'0'
) << std::setw(6) << us.count();
34
return
oss.str();
35
}
36
37
// Escape a string for JSON (handles quotes and backslashes)
38
std::string json_escape(std::string_view sv) {
39
std::string out;
40
out.reserve(sv.size());
41
for
(
char
c : sv) {
42
if
(c ==
'"'
|| c ==
'\\'
)
43
out +=
'\\'
;
44
out += c;
45
}
46
return
out;
47
}
48
}
// namespace
49
50
PotRegistry
&
PotRegistry::get
() noexcept {
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
}
59
60
void
PotRegistry::reset
() {
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
}
70
71
uint64_t
PotRegistry::on_created
(
PotType
t)
noexcept
{
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
}
77
78
void
PotRegistry::on_destroyed
(uint64_t
id
,
PotType
t,
size_t
force_calls,
79
TimePoint
created_at) {
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
}
87
88
void
PotRegistry::on_force_call
(
PotType
t)
noexcept
{
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
}
92
93
size_t
PotRegistry::type_force_calls
(
PotType
t)
const
noexcept
{
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
}
97
98
size_t
PotRegistry::total_force_calls
() const noexcept {
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
}
105
106
size_t
PotRegistry::type_alive
(
PotType
t)
const
noexcept
{
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
}
110
111
void
PotRegistry::write_summary
(
const
std::string &path)
const
{
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
}
141
142
}
// namespace eonc
PotRegistry.h
eonc::PotRegistry
Definition
PotRegistry.h:24
eonc::PotRegistry::m_next_id
std::atomic< uint64_t > m_next_id
Definition
PotRegistry.h:48
eonc::PotRegistry::m_type_stats
std::array< TypeStats, magic_enum::enum_count< PotType >()> m_type_stats
Definition
PotRegistry.h:43
eonc::PotRegistry::on_destroyed
void on_destroyed(uint64_t id, PotType t, size_t force_calls, TimePoint created_at)
Definition
PotRegistry.cpp:78
eonc::PotRegistry::on_created
uint64_t on_created(PotType t) noexcept
Definition
PotRegistry.cpp:71
eonc::PotRegistry::get
static PotRegistry & get() noexcept
Process-lifetime singleton.
Definition
PotRegistry.cpp:50
eonc::PotRegistry::type_force_calls
size_t type_force_calls(PotType t) const noexcept
Definition
PotRegistry.cpp:93
eonc::PotRegistry::reset
void reset()
Definition
PotRegistry.cpp:60
eonc::PotRegistry::total_force_calls
size_t total_force_calls() const noexcept
Definition
PotRegistry.cpp:98
eonc::PotRegistry::on_force_call
void on_force_call(PotType t) noexcept
Definition
PotRegistry.cpp:88
eonc::PotRegistry::m_records_mutex
std::mutex m_records_mutex
Definition
PotRegistry.h:45
eonc::PotRegistry::type_alive
size_t type_alive(PotType t) const noexcept
Definition
PotRegistry.cpp:106
eonc::PotRegistry::TimePoint
Clock::time_point TimePoint
Definition
PotRegistry.h:27
eonc::PotRegistry::write_summary
void write_summary(const std::string &path="_potcalls.json") const
Definition
PotRegistry.cpp:111
eonc::PotRegistry::m_records
std::vector< InstanceRecord > m_records
Definition
PotRegistry.h:46
eonc
RAII resource manager for the ARTn C library with global synchronization.
Definition
ARTnSaddleSearch.cpp:19
eonc::PotType
PotType
Definition
BaseStructures.h:36
eonc::PotRegistry::InstanceRecord
Definition
PotRegistry.h:29
client
PotRegistry.cpp
Generated by
1.17.0
Generated by
Doxygen 1.17.0
Analytics by
Antics
provided by
TurtleTech ehf