DNBLog.cpp revision 0e8147bd867e4cdaae9400f56d02c7aacd40a9b3
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 93bool 94DNBLogEnabledForAny (uint32_t mask) 95{ 96 if (g_log_callback) 97 return (g_log_bits & mask) != 0; 98 return false; 99} 100static inline void 101_DNBLogVAPrintf(uint32_t flags, const char *format, va_list args) 102{ 103 static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE); 104 PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex); 105 106 if (g_log_callback) 107 g_log_callback(g_log_baton, flags, format, args); 108} 109 110void 111_DNBLog(uint32_t flags, const char *format, ...) 112{ 113 va_list args; 114 va_start (args, format); 115 _DNBLogVAPrintf(flags, format, args); 116 va_end (args); 117} 118 119//---------------------------------------------------------------------- 120// Print debug strings if and only if the global g_debug is set to 121// a non-zero value. 122//---------------------------------------------------------------------- 123void 124_DNBLogDebug (const char *format, ...) 125{ 126 if (DNBLogEnabled () && g_debug) 127 { 128 va_list args; 129 va_start (args, format); 130 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args); 131 va_end (args); 132 } 133} 134 135 136//---------------------------------------------------------------------- 137// Print debug strings if and only if the global g_debug is set to 138// a non-zero value. 139//---------------------------------------------------------------------- 140void 141_DNBLogDebugVerbose (const char *format, ...) 142{ 143 if (DNBLogEnabled () && g_debug && g_verbose) 144 { 145 va_list args; 146 va_start (args, format); 147 _DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args); 148 va_end (args); 149 } 150} 151 152 153static uint32_t g_message_id = 0; 154 155//---------------------------------------------------------------------- 156// Prefix the formatted log string with process and thread IDs and 157// suffix it with a newline. 158//---------------------------------------------------------------------- 159void 160_DNBLogThreaded (const char *format, ...) 161{ 162 if (DNBLogEnabled ()) 163 { 164 //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); 165 166 char *arg_msg = NULL; 167 va_list args; 168 va_start (args, format); 169 ::vasprintf (&arg_msg, format, args); 170 va_end (args); 171 172 if (arg_msg != NULL) 173 { 174 static struct timeval g_timeval = { 0 , 0 }; 175 static struct timeval tv; 176 static struct timeval delta; 177 gettimeofday(&tv, NULL); 178 if (g_timeval.tv_sec == 0) 179 { 180 delta.tv_sec = 0; 181 delta.tv_usec = 0; 182 } 183 else 184 { 185 timersub (&tv, &g_timeval, &delta); 186 } 187 g_timeval = tv; 188 _DNBLog (DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s", 189 ++g_message_id, 190 delta.tv_sec, 191 delta.tv_usec, 192 getpid(), 193 mach_thread_self(), 194 arg_msg); 195 free (arg_msg); 196 } 197 } 198} 199 200//---------------------------------------------------------------------- 201// Prefix the formatted log string with process and thread IDs and 202// suffix it with a newline. 203//---------------------------------------------------------------------- 204void 205_DNBLogThreadedIf (uint32_t log_bit, const char *format, ...) 206{ 207 if (DNBLogEnabled () && (log_bit & g_log_bits) == log_bit) 208 { 209 //PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex()); 210 211 char *arg_msg = NULL; 212 va_list args; 213 va_start (args, format); 214 ::vasprintf (&arg_msg, format, args); 215 va_end (args); 216 217 if (arg_msg != NULL) 218 { 219 static struct timeval g_timeval = { 0 , 0 }; 220 static struct timeval tv; 221 static struct timeval delta; 222 gettimeofday(&tv, NULL); 223 if (g_timeval.tv_sec == 0) 224 { 225 delta.tv_sec = 0; 226 delta.tv_usec = 0; 227 } 228 else 229 { 230 timersub (&tv, &g_timeval, &delta); 231 } 232 g_timeval = tv; 233 _DNBLog (DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s", 234 ++g_message_id, 235 delta.tv_sec, 236 delta.tv_usec, 237 getpid(), 238 mach_thread_self(), 239 arg_msg); 240 free (arg_msg); 241 } 242 } 243} 244 245 246 247//---------------------------------------------------------------------- 248// Printing of errors that are not fatal. 249//---------------------------------------------------------------------- 250void 251_DNBLogError (const char *format, ...) 252{ 253 if (DNBLogEnabled ()) 254 { 255 char *arg_msg = NULL; 256 va_list args; 257 va_start (args, format); 258 ::vasprintf (&arg_msg, format, args); 259 va_end (args); 260 261 if (arg_msg != NULL) 262 { 263 _DNBLog (DNBLOG_FLAG_ERROR, "error: %s", arg_msg); 264 free (arg_msg); 265 } 266 } 267} 268 269//---------------------------------------------------------------------- 270// Printing of errors that ARE fatal. Exit with ERR exit code 271// immediately. 272//---------------------------------------------------------------------- 273void 274_DNBLogFatalError (int err, const char *format, ...) 275{ 276 if (DNBLogEnabled ()) 277 { 278 char *arg_msg = NULL; 279 va_list args; 280 va_start (args, format); 281 ::vasprintf (&arg_msg, format, args); 282 va_end (args); 283 284 if (arg_msg != NULL) 285 { 286 _DNBLog (DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg); 287 free (arg_msg); 288 } 289 ::exit (err); 290 } 291} 292 293 294//---------------------------------------------------------------------- 295// Printing of warnings that are not fatal only if verbose mode is 296// enabled. 297//---------------------------------------------------------------------- 298void 299_DNBLogVerbose (const char *format, ...) 300{ 301 if (DNBLogEnabled () && g_verbose) 302 { 303 va_list args; 304 va_start (args, format); 305 _DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args); 306 va_end (args); 307 } 308} 309 310//---------------------------------------------------------------------- 311// Printing of warnings that are not fatal only if verbose mode is 312// enabled. 313//---------------------------------------------------------------------- 314void 315_DNBLogWarningVerbose (const char *format, ...) 316{ 317 if (DNBLogEnabled () && g_verbose) 318 { 319 char *arg_msg = NULL; 320 va_list args; 321 va_start (args, format); 322 ::vasprintf (&arg_msg, format, args); 323 va_end (args); 324 325 if (arg_msg != NULL) 326 { 327 _DNBLog (DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s", arg_msg); 328 free (arg_msg); 329 } 330 } 331} 332//---------------------------------------------------------------------- 333// Printing of warnings that are not fatal. 334//---------------------------------------------------------------------- 335void 336_DNBLogWarning (const char *format, ...) 337{ 338 if (DNBLogEnabled ()) 339 { 340 char *arg_msg = NULL; 341 va_list args; 342 va_start (args, format); 343 ::vasprintf (&arg_msg, format, args); 344 va_end (args); 345 346 if (arg_msg != NULL) 347 { 348 _DNBLog (DNBLOG_FLAG_WARNING, "warning: %s", arg_msg); 349 free (arg_msg); 350 } 351 } 352} 353 354#endif 355