blob: c3d42a2a84da7ff0e2e7c54a281bba49bde126d8 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- DNBLog.cpp ----------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Created by Greg Clayton on 6/18/07.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DNBLog.h"
15
16static int g_debug = 0;
17static int g_verbose = 0;
18
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#if defined(DNBLOG_ENABLED)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "PThreadMutex.h"
22#include <mach/mach.h>
23#include <pthread.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include <stdarg.h>
Kate Stoneb9c1b512016-09-06 20:57:50 +000025#include <stdio.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include <stdlib.h>
Greg Claytone5219662010-12-03 06:02:24 +000027#include <sys/time.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include <unistd.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029
30uint32_t g_log_bits = 0;
31static DNBCallbackLog g_log_callback = NULL;
32static void *g_log_baton = NULL;
33
Kate Stoneb9c1b512016-09-06 20:57:50 +000034int DNBLogGetDebug() { return g_debug; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036void DNBLogSetDebug(int g) { g_debug = g; }
37
38int DNBLogGetVerbose() { return g_verbose; }
39
40void DNBLogSetVerbose(int v) { g_verbose = v; }
41
42bool DNBLogCheckLogBit(uint32_t bit) { return (g_log_bits & bit) != 0; }
43
44uint32_t DNBLogSetLogMask(uint32_t mask) {
45 uint32_t old = g_log_bits;
46 g_log_bits = mask;
47 return old;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048}
49
Kate Stoneb9c1b512016-09-06 20:57:50 +000050uint32_t DNBLogGetLogMask() { return g_log_bits; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton) {
53 g_log_callback = callback;
54 g_log_baton = baton;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055}
56
Kate Stoneb9c1b512016-09-06 20:57:50 +000057DNBCallbackLog DNBLogGetLogCallback() { return g_log_callback; }
58
59bool DNBLogEnabled() { return g_log_callback != NULL; }
60
61bool DNBLogEnabledForAny(uint32_t mask) {
62 if (g_log_callback)
63 return (g_log_bits & mask) != 0;
64 return false;
65}
66static inline void _DNBLogVAPrintf(uint32_t flags, const char *format,
67 va_list args) {
68 static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
69 PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex);
70
71 if (g_log_callback)
72 g_log_callback(g_log_baton, flags, format, args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073}
74
Kate Stoneb9c1b512016-09-06 20:57:50 +000075void _DNBLog(uint32_t flags, const char *format, ...) {
76 va_list args;
77 va_start(args, format);
78 _DNBLogVAPrintf(flags, format, args);
79 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
Kate Stoneb9c1b512016-09-06 20:57:50 +000082//----------------------------------------------------------------------
83// Print debug strings if and only if the global g_debug is set to
84// a non-zero value.
85//----------------------------------------------------------------------
86void _DNBLogDebug(const char *format, ...) {
87 if (DNBLogEnabled() && g_debug) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088 va_list args;
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 va_start(args, format);
90 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args);
91 va_end(args);
92 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093}
94
95//----------------------------------------------------------------------
96// Print debug strings if and only if the global g_debug is set to
97// a non-zero value.
98//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000099void _DNBLogDebugVerbose(const char *format, ...) {
100 if (DNBLogEnabled() && g_debug && g_verbose) {
101 va_list args;
102 va_start(args, format);
103 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args);
104 va_end(args);
105 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106}
107
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108static uint32_t g_message_id = 0;
109
110//----------------------------------------------------------------------
111// Prefix the formatted log string with process and thread IDs and
112// suffix it with a newline.
113//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114void _DNBLogThreaded(const char *format, ...) {
115 if (DNBLogEnabled()) {
116 // PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 char *arg_msg = NULL;
119 va_list args;
120 va_start(args, format);
121 ::vasprintf(&arg_msg, format, args);
122 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 if (arg_msg != NULL) {
125 static struct timeval g_timeval = {0, 0};
126 static struct timeval tv;
127 static struct timeval delta;
128 gettimeofday(&tv, NULL);
129 if (g_timeval.tv_sec == 0) {
130 delta.tv_sec = 0;
131 delta.tv_usec = 0;
132 } else {
133 timersub(&tv, &g_timeval, &delta);
134 }
135 g_timeval = tv;
Greg Clayton813ddfc2012-09-18 18:19:49 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 // Calling "mach_port_deallocate()" bumps the reference count on the
138 // thread
139 // port, so we need to deallocate it. mach_task_self() doesn't bump the
140 // ref
141 // count.
142 thread_port_t thread_self = mach_thread_self();
Greg Clayton813ddfc2012-09-18 18:19:49 +0000143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 _DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
145 ++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
146 thread_self, arg_msg);
147
148 mach_port_deallocate(mach_task_self(), thread_self);
149 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152}
153
154//----------------------------------------------------------------------
155// Prefix the formatted log string with process and thread IDs and
156// suffix it with a newline.
157//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158void _DNBLogThreadedIf(uint32_t log_bit, const char *format, ...) {
159 if (DNBLogEnabled() && (log_bit & g_log_bits) == log_bit) {
160 // PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 char *arg_msg = NULL;
163 va_list args;
164 va_start(args, format);
165 ::vasprintf(&arg_msg, format, args);
166 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 if (arg_msg != NULL) {
169 static struct timeval g_timeval = {0, 0};
170 static struct timeval tv;
171 static struct timeval delta;
172 gettimeofday(&tv, NULL);
173 if (g_timeval.tv_sec == 0) {
174 delta.tv_sec = 0;
175 delta.tv_usec = 0;
176 } else {
177 timersub(&tv, &g_timeval, &delta);
178 }
179 g_timeval = tv;
Greg Clayton813ddfc2012-09-18 18:19:49 +0000180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 // Calling "mach_port_deallocate()" bumps the reference count on the
182 // thread
183 // port, so we need to deallocate it. mach_task_self() doesn't bump the
184 // ref
185 // count.
186 thread_port_t thread_self = mach_thread_self();
Greg Clayton813ddfc2012-09-18 18:19:49 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 _DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
189 ++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
190 thread_self, arg_msg);
Greg Clayton813ddfc2012-09-18 18:19:49 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 mach_port_deallocate(mach_task_self(), thread_self);
Greg Clayton813ddfc2012-09-18 18:19:49 +0000193
Kate Stoneb9c1b512016-09-06 20:57:50 +0000194 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197}
198
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199//----------------------------------------------------------------------
200// Printing of errors that are not fatal.
201//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202void _DNBLogError(const char *format, ...) {
203 if (DNBLogEnabled()) {
204 char *arg_msg = NULL;
205 va_list args;
206 va_start(args, format);
207 ::vasprintf(&arg_msg, format, args);
208 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 if (arg_msg != NULL) {
211 _DNBLog(DNBLOG_FLAG_ERROR, "error: %s", arg_msg);
212 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215}
216
217//----------------------------------------------------------------------
218// Printing of errors that ARE fatal. Exit with ERR exit code
219// immediately.
220//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221void _DNBLogFatalError(int err, const char *format, ...) {
222 if (DNBLogEnabled()) {
223 char *arg_msg = NULL;
224 va_list args;
225 va_start(args, format);
226 ::vasprintf(&arg_msg, format, args);
227 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 if (arg_msg != NULL) {
230 _DNBLog(DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg);
231 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 ::exit(err);
234 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235}
236
237//----------------------------------------------------------------------
238// Printing of warnings that are not fatal only if verbose mode is
239// enabled.
240//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241void _DNBLogVerbose(const char *format, ...) {
242 if (DNBLogEnabled() && g_verbose) {
243 va_list args;
244 va_start(args, format);
245 _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args);
246 va_end(args);
247 }
248}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250//----------------------------------------------------------------------
251// Printing of warnings that are not fatal only if verbose mode is
252// enabled.
253//----------------------------------------------------------------------
254void _DNBLogWarningVerbose(const char *format, ...) {
255 if (DNBLogEnabled() && g_verbose) {
256 char *arg_msg = NULL;
257 va_list args;
258 va_start(args, format);
259 ::vasprintf(&arg_msg, format, args);
260 va_end(args);
261
262 if (arg_msg != NULL) {
263 _DNBLog(DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s",
264 arg_msg);
265 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268}
269//----------------------------------------------------------------------
270// Printing of warnings that are not fatal.
271//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272void _DNBLogWarning(const char *format, ...) {
273 if (DNBLogEnabled()) {
274 char *arg_msg = NULL;
275 va_list args;
276 va_start(args, format);
277 ::vasprintf(&arg_msg, format, args);
278 va_end(args);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 if (arg_msg != NULL) {
281 _DNBLog(DNBLOG_FLAG_WARNING, "warning: %s", arg_msg);
282 free(arg_msg);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000283 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000285}
286
287#endif