-
Notifications
You must be signed in to change notification settings - Fork 47
/
logging.h
352 lines (295 loc) · 12.1 KB
/
logging.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
//==============================================================================
// Copyright (c) 2016-2023 Advanced Micro Devices, Inc. All rights reserved.
/// @author AMD Developer Tools Team
/// @file
/// @brief Logging utility.
//==============================================================================
#ifndef GPU_PERF_API_COMMON_LOGGING_H_
#define GPU_PERF_API_COMMON_LOGGING_H_
#ifdef _WIN32
#include <Windows.h>
#endif
#ifdef _LINUX
#include <pthread.h>
#include <string.h>
#define EnterCriticalSection pthread_mutex_lock
#define LeaveCriticalSection pthread_mutex_unlock
#include <stdarg.h>
#include <stdio.h>
#endif
#include <string>
#include <sstream>
#include <mutex>
#include <map>
#include <thread>
#include <fstream>
#include "TSingleton.h"
#include "gpu_performance_api/gpu_perf_api_function_types.h"
#include "gpu_performance_api/gpu_perf_api_types.h"
#define ENABLE_TRACING 1 ///< Macro to determine if tracing is enabled.
#if ENABLE_TRACING
#undef TRACE_FUNCTION
/// Macro for tracing function calls.
#define TRACE_FUNCTION(func) ScopeTrace temp_scope_trace_object(#func) ///< Macro used for tracing functions.
#undef TRACE_PRIVATE_FUNCTION
#undef TRACE_PRIVATE_FUNCTION_WITH_ARGS
/// Macro for tracing private function calls.
#define TRACE_PRIVATE_FUNCTION(func) ///< Macro used for tracing private functions.
#define TRACE_PRIVATE_FUNCTION_WITH_ARGS(func, ...) ///< Macro used for tracing private function with parameters.
#else // disable trace functions.
#undef TRACE_FUNCTION
#define TRACE_FUNCTION(func) ///< Macro used for tracing functions.
#undef TRACE_PRIVATE_FUNCTION
#define TRACE_PRIVATE_FUNCTION(func) ///< Macro used for tracing private functions.
#define TRACE_PRIVATE_FUNCTION_WITH_ARGS(func, ...) ///< Macro used for tracing private function with parameters.
#endif // trace functions.
#ifdef __GNUC__
#define GPA_ATTRIBUTE_PRINTF(msg, args) __attribute__((format(printf, msg, args)))
#else
#define GPA_ATTRIBUTE_PRINTF(msg, args)
#endif // !__GNUC__
/// @brief Internal GPA logger function.
///
/// @param [in] log_type Logging type.
/// @param [in] log_msg Logging message.
extern void GpaInternalLogger(GpaLoggingType log_type, const char* log_msg);
#define GPA_INTERNAL_LOG(func, ...) \
std::stringstream log_additional_message; \
log_additional_message << "ThreadId: " << std::this_thread::get_id() << " " << #func << ": " << __VA_ARGS__; \
GpaInternalLogger(kGpaLoggingInternal, log_additional_message.str().c_str());
/// @brief Passes log messages of various types to a user-supplied callback function
/// if the user has elected to receive messages of that particular type.
class GpaLogger : public TSingleton<GpaLogger>
{
public:
/// @brief Sets the type of message the user would like to be informed of and a pointer to the callback function.
///
/// @param [in] logging_type The type of messages to pass on to the callback function.
/// @param [in] logging_callback A pointer to the callback function.
void SetLoggingCallback(GpaLoggingType logging_type, GpaLoggingCallbackPtrType logging_callback);
/// @brief Passes the supplied message to the callback function if the user has accepted that type of message.
///
/// @param [in] log_type The type of message being supplied.
/// @param [in] log_message The message to pass along.
void Log(GpaLoggingType log_type, const char* log_message);
/// @brief Passes the supplied formatted message to the callback function if the user has accepted that type of message.
///
/// @param [in] type The type of message being supplied.
/// @param [in] msg_fmt The message to format.
/// @param [in] args Variable arguments supplied for the message.
void Logfv(GpaLoggingType type, const char* msg_fmt, va_list args)
{
// If the supplied message type is among those that the user wants be notified of,
// then pass the message along.
if (type & logging_type_)
{
EnterCriticalSection(&lock_handle);
// Format string.
char buffer[1024 * 5];
buffer[0] = '\0';
#ifdef WIN32
vsnprintf_s(buffer, sizeof(buffer), msg_fmt, args);
#else
vsnprintf(buffer, sizeof(buffer), msg_fmt, args);
#endif
Log(type, buffer);
LeaveCriticalSection(&lock_handle);
}
}
/// @brief Passes the supplied formatted message to the callback function if the user has accepted that type of message.
///
/// @param [in] type The type of message being supplied.
/// @param [in] msg_fmt The message to format.
void Logf(GpaLoggingType type, const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(3, 4)
{
va_list args;
va_start(args, msg_fmt);
Logfv(type, msg_fmt, args);
va_end(args);
}
/// @brief Logs an error message.
///
/// @param [in] msg_fmt The message to format and pass along.
inline void LogError(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingError, msg_fmt, args);
va_end(args);
}
/// @brief Logs an informational message.
///
/// @param [in] msg_fmt The message to format and pass along.
inline void LogMessage(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingMessage, msg_fmt, args);
va_end(args);
}
/// @brief Logs a trace message.
///
/// @param [in] msg_fmt The message to format and pass along.
inline void LogTrace(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingTrace, msg_fmt, args);
va_end(args);
}
/// @brief Logs a formatted message in internal builds; does nothing in release.
///
/// @param [in] msg_fmt The message to format and pass along.
void LogDebugMessage(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingDebugMessage, msg_fmt, args);
va_end(args);
}
/// @brief Logs a formatted error message in debug builds; does nothing in release.
///
/// @param [in] msg_fmt The message to format and pass along.
void LogDebugError(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingDebugError, msg_fmt, args);
va_end(args);
}
/// @brief Logs a formatted error message in debug builds; does nothing in release.
///
/// @param [in] msg_fmt The message to format and pass along.
void LogDebugTrace(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingDebugTrace, msg_fmt, args);
va_end(args);
}
/// @brief Logs a formatted message in internal builds; does nothing in public builds.
///
/// @param [in] msg_fmt The message to format and pass along.
void LogDebugCounterDefs(const char* msg_fmt, ...) GPA_ATTRIBUTE_PRINTF(2, 3)
{
va_list args;
va_start(args, msg_fmt);
Logfv(kGpaLoggingDebugCounterDefinitions, msg_fmt, args);
va_end(args);
}
/// @brief Checks whether the tracing is enabled or not.
///
/// @return True if either tracing or debug tracing is enabled otherwise false.
bool IsTracingEnabled() const
{
if (nullptr != logging_callback_)
{
return logging_type_ & kGpaLoggingTrace || logging_type_ & kGpaLoggingDebugTrace;
}
return false;
}
/// Internal logging file stream.
std::fstream internal_logging_file_stream_;
/// Internal logging file.
std::string internal_log_file_name_;
protected:
/// User selected logging type that defines what messages they want to be notified of.
GpaLoggingType logging_type_;
/// User-supplied callback function.
GpaLoggingCallbackPtrType logging_callback_;
/// Internal logger of GPA for debugging purposes.
GpaLoggingCallbackPtrType gpa_internal_logger_ = GpaInternalLogger;
/// Mutex for internal logging flag.
std::mutex internal_logging_mutex_;
/// Internal logging flag.
bool enable_internal_logging_;
#ifdef _WIN32
CRITICAL_SECTION lock_handle; ///< Lock for thread-safe access.
#endif
#ifdef _LINUX
pthread_mutex_t lock_handle; ///< Lock for thread-safe access.
#endif
private:
friend TSingleton<GpaLogger>;
/// @brief Default constructor.
GpaLogger();
/// @brief Virtual destructor.
virtual ~GpaLogger();
/// @brief Don't allow the singleton to be copies.
GpaLogger(const GpaLogger&) = delete;
/// @brief Don't allow the singleton to be assigned.
void operator=(const GpaLogger&) = delete;
};
// define C-style functions for simplified logging.
/// Macro for logging.
#define GPA_LOG GpaLogger::Instance()->Log
/// Macro for logging of errors.
#define GPA_LOG_ERROR GpaLogger::Instance()->LogError
/// Macro for logging of messages.
#define GPA_LOG_MESSAGE GpaLogger::Instance()->LogMessage
/// Macro for logging of trace items.
#define GPA_LOG_TRACE GpaLogger::Instance()->LogTrace
/// Macro for debug logging of messages.
#define GPA_LOG_DEBUG_MESSAGE GpaLogger::Instance()->LogDebugMessage
/// Macro for debug logging of errors.
#define GPA_LOG_DEBUG_ERROR GpaLogger::Instance()->LogDebugError
/// Macro for debug logging of trace items.
#define GPA_LOG_DEBUG_TRACE GpaLogger::Instance()->LogDebugTrace
/// Macro for debug logging of counter definitions.
#define GPA_LOG_DEBUG_COUNTER_DEFS GpaLogger::Instance()->LogDebugCounterDefs
/// @brief Utility class for tracing the start and end of functions.
class GpaTracer : public TSingleton<GpaTracer>
{
public:
/// @brief Should be called when a function is entered.
///
/// @param [in] function_name The function that is being entered.
void EnterFunction(const char* function_name);
/// @brief Should be called when a function is exited.
///
/// @param [in] function_name The function that is being left.
void LeaveFunction(const char* function_name);
/// @brief Called if a function has additional data to output.
///
/// Information is tabbed under the function.
///
/// @param [in] data The additional data to output.
void OutputFunctionData(const char* data);
private:
friend TSingleton<GpaTracer>;
/// @brief Default constructor.
GpaTracer();
/// @brief Don't allow singleton copies.
GpaTracer(const GpaTracer&) = delete;
/// @brief Don't allow singleton assignment elsewhere.
void operator=(const GpaTracer&) = delete;
/// @brief Returns the pointer to the tab counter.
///
/// @param [out] current_thread_id Thread id of the caller.
///
/// @return Pointer to the tab counter.
std::map<std::thread::id, int32_t>::iterator GetTabCounter(std::thread::id* current_thread_id);
/// Indicates whether to only show the top level of functions (true), or also show nested function calls (false).
bool top_level_only_;
/// Mutex for the thread and tab counter map.
std::mutex tracer_mutex_;
/// Map of the thread and its associated tab counter.
std::map<std::thread::id, int32_t> thread_tab_count_map_;
};
/// @brief Allows for easy tracing of exiting a function.
///
/// Calls GPATracer::EnterFunction in the constructor and GpaTracer::LeaveFunction in the destructor.
class ScopeTrace
{
public:
/// @brief Constructor which calls GPATracer::EnterFunction.
///
/// @param [in] trace_function The function which is being traced.
ScopeTrace(const char* trace_function);
/// @brief Destructor which calls GPATracer::LeaveFunction.
~ScopeTrace();
protected:
/// Stores the function being traced.
std::string trace_function_;
};
#endif // GPU_PERF_API_COMMON_LOGGING_H_