OpenTTD Source 20260911-master-gee2b2ac12a
debug.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#ifndef DEBUG_H
11#define DEBUG_H
12
13#include "cpu.h"
14#include <chrono>
15#include "debug_type.h"
16#include "core/enum_type.hpp"
17#include "core/format.hpp"
18
25inline bool IsVisibleSeverity(Facility facility, Severity severity)
26{
28 return _debug_level[facility] >= severity;
29}
30
37#define Debug(facility, severity, format_string, ...) do { if ((severity) == Severity::Critical || IsVisibleSeverity((facility), (severity))) DebugPrint(facility, severity, fmt::format(FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__)); } while (false)
38void DebugPrint(Facility facility, Severity severity, std::string &&message);
39
40void DumpDebugFacilityNames(std::back_insert_iterator<std::string> &output_iterator);
41using SetDebugStringErrorFunc = void(std::string_view);
42void SetDebugString(std::string_view s, SetDebugStringErrorFunc error_func);
43std::string GetDebugString();
44
56struct TicToc {
58 struct State {
59 const std::string_view name;
60 const std::optional<uint32_t> max_count;
61 uint32_t count = 0;
62 uint64_t chrono_sum = 0;
63
64 using States = std::vector<State *>;
65
66 State(std::string_view name, std::optional<uint32_t> max_count = {}) : name(name), max_count(max_count)
67 {
68 GetStates().push_back(this);
69 }
70
73 {
74 /* Container might be already destroyed. */
75 if (!GetStates().empty()) std::erase(GetStates(), this);
76 }
77
78 static States &GetStates()
79 {
80 thread_local static States s_states;
81 return s_states;
82 }
83
84 void OutputAndReset(const std::string_view prefix = "")
85 {
86 Debug(Facility::Misc, Severity::Critical, "[{}] [{}] {} calls in {} us [avg: {:.1f} us]", prefix, this->name, this->count, this->chrono_sum, this->chrono_sum / static_cast<double>(this->count));
87 this->count = 0;
88 this->chrono_sum = 0;
89 }
90 };
91
92 State &state;
93 std::chrono::high_resolution_clock::time_point chrono_start;
94
95 inline TicToc(State &state) : state(state), chrono_start(std::chrono::high_resolution_clock::now()) { }
96
98 inline ~TicToc()
99 {
100 this->state.chrono_sum += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - this->chrono_start)).count();
101 this->state.count++;
102 if (this->state.max_count.has_value() && this->state.count == this->state.max_count.value()) {
103 this->state.OutputAndReset("MaxCount");
104 }
105 }
106
107 static void Tick(const std::string_view prefix)
108 {
109 for (auto state : State::GetStates()) {
110 if (state->max_count.has_value() || state->count == 0) continue;
111 state->OutputAndReset(prefix);
112 }
113 }
114};
115
116void ShowInfoI(std::string_view str);
117#define ShowInfo(format_string, ...) ShowInfoI(fmt::format(FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__))
118
119std::string GetLogPrefix(bool force = false);
120
123
124#endif /* DEBUG_H */
Functions related to CPU specific instructions.
EnumIndexArray< Severity, Facility, Facility::End > _debug_level
Severity level for each debug facility.
Definition debug.cpp:40
void SetDebugString(std::string_view s, SetDebugStringErrorFunc error_func)
Set debugging levels by parsing the text in s.
Definition debug.cpp:122
void DebugReconsiderSendRemoteMessages()
Reconsider whether we need to send debug messages to either NetworkAdminConsole or IConsolePrint.
Definition debug.cpp:231
bool IsVisibleSeverity(Facility facility, Severity severity)
Test if debug severity is visible for the given facility.
Definition debug.h:25
std::string GetLogPrefix(bool force=false)
Get the prefix for logs.
Definition debug.cpp:191
void DumpDebugFacilityNames(std::back_insert_iterator< std::string > &output_iterator)
Dump the available debug facility names in the help text.
Definition debug.cpp:65
std::string GetDebugString()
Print out the current debug-level.
Definition debug.cpp:172
#define Debug(facility, severity, format_string,...)
Output a line of debugging information.
Definition debug.h:37
void DebugSendRemoteMessages()
Send the queued Debug messages to either NetworkAdminConsole or IConsolePrint from the GameLoop threa...
Definition debug.cpp:207
void DebugPrint(Facility facility, Severity severity, std::string &&message)
Internal function for outputting the debug line.
Definition debug.cpp:88
Types related to debugging.
Facility
Debug facilities.
Definition debug_type.h:28
@ Misc
Misc message facility.
Definition debug_type.h:32
Severity
Debug message severity levels.
Definition debug_type.h:14
@ Critical
Critical, user should know about this.
Definition debug_type.h:15
Type (helpers) for enums.
EnumClassIndexContainer< std::array< T, to_underlying(N)>, Index > EnumIndexArray
A typedef for EnumClassIndexContainer using std::array as the backing container type.
String formatting functions and helpers.
Persistent state for TicToc profiling.
Definition debug.h:58
~State()
Remove ourselves from the thread local states.
Definition debug.h:72
std::chrono::high_resolution_clock::time_point chrono_start
real time count.
Definition debug.h:93
~TicToc()
Update the state with the time since the constructor call.
Definition debug.h:98