DNBLog.cpp revision c1f4587c3cc1b6de2f59d472762e9eb16819feff
1//===-- 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 19#if defined (DNBLOG_ENABLED) 20 21#include <stdio.h> 22#include <stdarg.h> 23#include <stdlib.h> 24#include <sys/time.h> 25#include <unistd.h> 26#include <mach/mach.h> 27#include <pthread.h> 28#include "PThreadMutex.h" 29 30uint32_t g_log_bits = 0; 31static DNBCallbackLog g_log_callback = NULL; 32static void *g_log_baton = NULL; 33 34 35int 36DNBLogGetDebug () 37{ 38 return g_debug; 39} 40 41 42void 43DNBLogSetDebug (int g) 44{ 45 g_debug = g; 46} 47 48int 49DNBLogGetVerbose () 50{ 51 return g_verbose; 52} 53 54void 55DNBLogSetVerbose (int v) 56{ 57 g_verbose = v; 58} 59 60bool 61DNBLogCheckLogBit (uint32_t bit) 62{ 63 return (g_log_bits & bit) != 0; 64} 65 66uint32_t 67DNBLogSetLogMask (uint32_t mask) 68{ 69 uint32_t old = g_log_bits; 70 g_log_bits = mask; 71 return old; 72} 73 74uint32_t 75DNBLogGetLogMask () 76{ 77 return g_log_bits; 78} 79 80void 81DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) 82{ 83 g_log_callback = callback; 84 g_log_baton = baton; 85} 86 87bool 88DNBLogEnabled () 89{ 90 return g_log_callback != NULL; 91} 92 93static inline void 94_DNBLogVAPrintf(uint32_t flags, const char *format, va_list args) 95{ 96 static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); 97 PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex); 98 99 if (g_log_callback) 100 g_log_callback(g_log_baton, flags, format, args); 101} 102 103void 104_DNBLog(uint32_t flags, const char *format, ...) 105{ 106 va_list args; 107 va_start (args, format); 108 _DNBLogVAPrintf(flags, format, args); 109 va_end (args); 110} 111 112//---------------------------------------------------------------------- 113// Print debug strings if and only if the global g_debug is set to 114// a non-zero value. 115//---------------------------------------------------------------------- 116void 117_DNBLogDebug (const char *format, ...) 118{ 119 if (DNBLogEnabled () && g_debug) 120 { 121 va_list args; 122 va_start (args, format); 123 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args); 124 va_end (args); 125 } 126} 127 128 129//---------------------------------------------------------------------- 130// Print debug strings if and only if the global g_debug is set to 131// a non-zero value. 132//---------------------------------------------------------------------- 133void 134_DNBLogDebugVerbose (const char *format, ...) 135{ 136 if (DNBLogEnabled () && g_debug && g_verbose) 137 { 138 va_list args; 139 va_start (args, format); 140 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args); 141 va_end (args); 142 } 143} 144 145 146static uint32_t g_message_id = 0; 147 148//---------------------------------------------------------------------- 149// Prefix the formatted log string with process and thread IDs and 150// suffix it with a newline. 151//---------------------------------------------------------------------- 152void 153_DNBLogThreaded (const char *format, ...) 154{ 155 if (DNBLogEnabled ()) 156 { 157 //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); 158 159 char *arg_msg = NULL; 160 va_list args; 161 va_start (args, format); 162 ::vasprintf (&arg_msg, format, args); 163 va_end (args); 164 165 if (arg_msg != NULL) 166 { 167 static struct timeval g_timeval = { 0 , 0 }; 168 static struct timeval tv; 169 static struct timeval delta; 170 gettimeofday(&tv, NULL); 171 if (g_timeval.tv_sec == 0) 172 { 173 delta.tv_sec = 0; 174 delta.tv_usec = 0; 175 } 176 else 177 { 178 timersub (&tv, &g_timeval, &delta); 179 } 180 g_timeval = tv; 181 _DNBLog (DNBLOG_FLAG_THREADED, "%u +%u.%06u sec [%4.4x/%4.4x]: %s", 182 ++g_message_id, 183 delta.tv_sec, 184 delta.tv_usec, 185 getpid(), 186 mach_thread_self(), 187 arg_msg); 188 free (arg_msg); 189 } 190 } 191} 192 193//---------------------------------------------------------------------- 194// Prefix the formatted log string with process and thread IDs and 195// suffix it with a newline. 196//---------------------------------------------------------------------- 197void 198_DNBLogThreadedIf (uint32_t log_bit, const char *format, ...) 199{ 200 if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit) 201 { 202 //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); 203 204 char *arg_msg = NULL; 205 va_list args; 206 va_start (args, format); 207 ::vasprintf (&arg_msg, format, args); 208 va_end (args); 209 210 if (arg_msg != NULL) 211 { 212 static struct timeval g_timeval = { 0 , 0 }; 213 static struct timeval tv; 214 static struct timeval delta; 215 gettimeofday(&tv, NULL); 216 if (g_timeval.tv_sec == 0) 217 { 218 delta.tv_sec = 0; 219 delta.tv_usec = 0; 220 } 221 else 222 { 223 timersub (&tv, &g_timeval, &delta); 224 } 225 g_timeval = tv; 226 _DNBLog (DNBLOG_FLAG_THREADED, "%u +%u.%06u sec [%4.4x/%4.4x]: %s", 227 ++g_message_id, 228 delta.tv_sec, 229 delta.tv_usec, 230 getpid(), 231 mach_thread_self(), 232 arg_msg); 233 free (arg_msg); 234 } 235 } 236} 237 238 239 240//---------------------------------------------------------------------- 241// Printing of errors that are not fatal. 242//---------------------------------------------------------------------- 243void 244_DNBLogError (const char *format, ...) 245{ 246 if (DNBLogEnabled ()) 247 { 248 char *arg_msg = NULL; 249 va_list args; 250 va_start (args, format); 251 ::vasprintf (&arg_msg, format, args); 252 va_end (args); 253 254 if (arg_msg != NULL) 255 { 256 _DNBLog (DNBLOG_FLAG_ERROR, "error: %s", arg_msg); 257 free (arg_msg); 258 } 259 } 260} 261 262//---------------------------------------------------------------------- 263// Printing of errors that ARE fatal. Exit with ERR exit code 264// immediately. 265//---------------------------------------------------------------------- 266void 267_DNBLogFatalError (int err, const char *format, ...) 268{ 269 if (DNBLogEnabled ()) 270 { 271 char *arg_msg = NULL; 272 va_list args; 273 va_start (args, format); 274 ::vasprintf (&arg_msg, format, args); 275 va_end (args); 276 277 if (arg_msg != NULL) 278 { 279 _DNBLog (DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg); 280 free (arg_msg); 281 } 282 ::exit (err); 283 } 284} 285 286 287//---------------------------------------------------------------------- 288// Printing of warnings that are not fatal only if verbose mode is 289// enabled. 290//---------------------------------------------------------------------- 291void 292_DNBLogVerbose (const char *format, ...) 293{ 294 if (DNBLogEnabled () && g_verbose) 295 { 296 va_list args; 297 va_start (args, format); 298 _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args); 299 va_end (args); 300 } 301} 302 303//---------------------------------------------------------------------- 304// Printing of warnings that are not fatal only if verbose mode is 305// enabled. 306//---------------------------------------------------------------------- 307void 308_DNBLogWarningVerbose (const char *format, ...) 309{ 310 if (DNBLogEnabled () && g_verbose) 311 { 312 char *arg_msg = NULL; 313 va_list args; 314 va_start (args, format); 315 ::vasprintf (&arg_msg, format, args); 316 va_end (args); 317 318 if (arg_msg != NULL) 319 { 320 _DNBLog (DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s", arg_msg); 321 free (arg_msg); 322 } 323 } 324} 325//---------------------------------------------------------------------- 326// Printing of warnings that are not fatal. 327//---------------------------------------------------------------------- 328void 329_DNBLogWarning (const char *format, ...) 330{ 331 if (DNBLogEnabled ()) 332 { 333 char *arg_msg = NULL; 334 va_list args; 335 va_start (args, format); 336 ::vasprintf (&arg_msg, format, args); 337 va_end (args); 338 339 if (arg_msg != NULL) 340 { 341 _DNBLog (DNBLOG_FLAG_WARNING, "warning: %s", arg_msg); 342 free (arg_msg); 343 } 344 } 345} 346 347#endif 348