6#if defined(TESS_ENABLE_DIAGNOSTICS)
8#define TESS_DIAGNOSTICS_ENABLED 1
10#define TESS_DIAGNOSTIC_ONLY(expr) \
15#define TESS_DIAGNOSTIC_INC(counter) \
20#define TESS_DIAGNOSTIC_ADD(counter, value) \
22 (counter) += (value); \
25#define TESS_DIAG_EVENT(name) \
27 ::tess::diagnostics::event_##name(); \
30#define TESS_DIAG_EVENT_VALUE(name, value) \
32 ::tess::diagnostics::event_##name(value); \
35#define TESS_DIAGNOSTICS_ENABLED 0
36#define TESS_DIAGNOSTIC_ONLY(expr) \
39#define TESS_DIAGNOSTIC_INC(counter) \
42#define TESS_DIAGNOSTIC_ADD(counter, value) \
45#define TESS_DIAG_EVENT(name) \
48#define TESS_DIAG_EVENT_VALUE(name, value) \
53namespace tess::diagnostics {
55#if TESS_DIAGNOSTICS_ENABLED
58 std::uint64_t scratch_clear_calls = 0;
59 std::uint64_t scratch_clear_nodes = 0;
60 std::uint64_t initializations = 0;
61 std::uint64_t start_passability_checks = 0;
62 std::uint64_t goal_passability_checks = 0;
63 std::uint64_t heap_pushes = 0;
64 std::uint64_t heap_pops = 0;
65 std::uint64_t stale_pops = 0;
66 std::uint64_t closed_pops = 0;
67 std::uint64_t neighbor_candidates = 0;
68 std::uint64_t passability_checks = 0;
69 std::uint64_t cost_reads = 0;
70 std::uint64_t blocked_neighbors = 0;
71 std::uint64_t closed_neighbors = 0;
72 std::uint64_t relax_attempts = 0;
73 std::uint64_t relax_successes = 0;
74 std::uint64_t touched_nodes = 0;
75 std::uint64_t heuristic_calls = 0;
76 std::uint64_t reconstructed_nodes = 0;
83 std::uint64_t allocations = 0;
84 std::uint64_t allocation_bytes = 0;
85 std::uint64_t deallocations = 0;
86 std::uint64_t deallocation_bytes = 0;
93 std::uint64_t phase_calls = 0;
94 std::uint64_t phase_operations = 0;
95 std::uint64_t phase_invalid_ranges = 0;
96 std::uint64_t phase_failures = 0;
97 std::uint64_t partitioned_phase_calls = 0;
98 std::uint64_t dirty_partitions = 0;
99 std::uint64_t scoped_thread_calls = 0;
100 std::uint64_t scoped_thread_workers = 0;
101 std::uint64_t worker_pool_calls = 0;
102 std::uint64_t worker_pool_workers = 0;
103 std::uint64_t dirty_records_collected = 0;
104 std::uint64_t dirty_chunks_merged = 0;
109inline thread_local PathCounters* active_path_counters =
nullptr;
114class ScopedPathCounters {
116 explicit ScopedPathCounters(
PathCounters& counters) noexcept
117 : previous_{active_path_counters} {
118 active_path_counters = &counters;
121 ScopedPathCounters(
const ScopedPathCounters&) =
delete;
122 auto operator=(
const ScopedPathCounters&) -> ScopedPathCounters& =
delete;
124 ~ScopedPathCounters() { active_path_counters = previous_; }
133class ScopedAllocationCounters {
136 : previous_{active_allocation_counters} {
137 active_allocation_counters = &counters;
140 ScopedAllocationCounters(
const ScopedAllocationCounters&) =
delete;
141 auto operator=(
const ScopedAllocationCounters&)
142 -> ScopedAllocationCounters& =
delete;
144 ~ScopedAllocationCounters() { active_allocation_counters = previous_; }
153class ScopedQueuedPhaseCounters {
156 : previous_{active_queued_phase_counters} {
157 active_queued_phase_counters = &counters;
160 ScopedQueuedPhaseCounters(
const ScopedQueuedPhaseCounters&) =
delete;
161 auto operator=(
const ScopedQueuedPhaseCounters&)
162 -> ScopedQueuedPhaseCounters& =
delete;
164 ~ScopedQueuedPhaseCounters() { active_queued_phase_counters = previous_; }
171inline void record_allocation(std::size_t size)
noexcept {
172 if (active_allocation_counters !=
nullptr) {
173 ++active_allocation_counters->allocations;
174 active_allocation_counters->allocation_bytes += size;
179inline void record_deallocation(std::size_t size = 0) noexcept {
180 if (active_allocation_counters !=
nullptr) {
181 ++active_allocation_counters->deallocations;
182 active_allocation_counters->deallocation_bytes += size;
187inline void event_path_clear(std::uint64_t nodes)
noexcept {
188 if (active_path_counters !=
nullptr) {
189 ++active_path_counters->scratch_clear_calls;
190 active_path_counters->scratch_clear_nodes += nodes;
195inline void event_path_initialize() noexcept {
196 if (active_path_counters !=
nullptr) {
197 ++active_path_counters->initializations;
202inline void event_path_start_passability_check() noexcept {
203 if (active_path_counters !=
nullptr) {
204 ++active_path_counters->start_passability_checks;
209inline void event_path_goal_passability_check() noexcept {
210 if (active_path_counters !=
nullptr) {
211 ++active_path_counters->goal_passability_checks;
216inline void event_path_heap_push() noexcept {
217 if (active_path_counters !=
nullptr) {
218 ++active_path_counters->heap_pushes;
223inline void event_path_heap_pop() noexcept {
224 if (active_path_counters !=
nullptr) {
225 ++active_path_counters->heap_pops;
230inline void event_path_skip_pop(
bool closed)
noexcept {
231 if (active_path_counters !=
nullptr) {
233 ++active_path_counters->closed_pops;
235 ++active_path_counters->stale_pops;
241inline void event_path_neighbor_candidate() noexcept {
242 if (active_path_counters !=
nullptr) {
243 ++active_path_counters->neighbor_candidates;
248inline void event_path_passability_check() noexcept {
249 if (active_path_counters !=
nullptr) {
250 ++active_path_counters->passability_checks;
255inline void event_path_cost_read() noexcept {
256 if (active_path_counters !=
nullptr) {
257 ++active_path_counters->cost_reads;
262inline void event_path_neighbor_blocked() noexcept {
263 if (active_path_counters !=
nullptr) {
264 ++active_path_counters->blocked_neighbors;
269inline void event_path_neighbor_closed() noexcept {
270 if (active_path_counters !=
nullptr) {
271 ++active_path_counters->closed_neighbors;
276inline void event_path_relax_attempt() noexcept {
277 if (active_path_counters !=
nullptr) {
278 ++active_path_counters->relax_attempts;
283inline void event_path_relax_success() noexcept {
284 if (active_path_counters !=
nullptr) {
285 ++active_path_counters->relax_successes;
290inline void event_path_touch_node() noexcept {
291 if (active_path_counters !=
nullptr) {
292 ++active_path_counters->touched_nodes;
297inline void event_path_heuristic() noexcept {
298 if (active_path_counters !=
nullptr) {
299 ++active_path_counters->heuristic_calls;
304inline void event_path_reconstruct_node() noexcept {
305 if (active_path_counters !=
nullptr) {
306 ++active_path_counters->reconstructed_nodes;
311inline void event_queued_phase_execute(std::uint64_t operations)
noexcept {
312 if (active_queued_phase_counters !=
nullptr) {
313 ++active_queued_phase_counters->phase_calls;
314 active_queued_phase_counters->phase_operations += operations;
319inline void event_queued_phase_invalid_range() noexcept {
320 if (active_queued_phase_counters !=
nullptr) {
321 ++active_queued_phase_counters->phase_invalid_ranges;
326inline void event_queued_phase_failure() noexcept {
327 if (active_queued_phase_counters !=
nullptr) {
328 ++active_queued_phase_counters->phase_failures;
333inline void event_queued_partitioned_phase(std::uint64_t partitions)
noexcept {
334 if (active_queued_phase_counters !=
nullptr) {
335 ++active_queued_phase_counters->partitioned_phase_calls;
336 active_queued_phase_counters->dirty_partitions += partitions;
341inline void event_queued_scoped_thread_dispatch(
342 std::uint64_t workers)
noexcept {
343 if (active_queued_phase_counters !=
nullptr) {
344 ++active_queued_phase_counters->scoped_thread_calls;
345 active_queued_phase_counters->scoped_thread_workers += workers;
350inline void event_queued_worker_pool_dispatch(std::uint64_t workers)
noexcept {
351 if (active_queued_phase_counters !=
nullptr) {
352 ++active_queued_phase_counters->worker_pool_calls;
353 active_queued_phase_counters->worker_pool_workers += workers;
358inline void event_queued_dirty_collect(std::uint64_t records)
noexcept {
359 if (active_queued_phase_counters !=
nullptr) {
360 active_queued_phase_counters->dirty_records_collected += records;
365inline void event_queued_dirty_merge(std::uint64_t chunks)
noexcept {
366 if (active_queued_phase_counters !=
nullptr) {
367 active_queued_phase_counters->dirty_chunks_merged += chunks;
Definition diagnostics.h:82
Definition diagnostics.h:57
Definition diagnostics.h:92