1/* 2 * Copyright 2003-2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "DebugSupport.h" 8 9#include <errno.h> 10#include <fcntl.h> 11#include <stdarg.h> 12#include <stdio.h> 13#include <string.h> 14#include <unistd.h> 15 16#ifdef __HAIKU__ 17 18#include <OS.h> 19 20 21/*! 22 \file Debug.cpp 23 \brief Defines debug output function with printf() signature printing 24 into a file. 25 26 \note The initialization is not thread safe! 27*/ 28 29 30// locking support 31static int32 init_counter = 0; 32static sem_id dbg_printf_sem = -1; 33static thread_id dbg_printf_thread = -1; 34static int dbg_printf_nesting = 0; 35 36 37#if DEBUG_PRINT 38static int out = -1; 39#endif 40 41 42status_t 43init_debugging() 44{ 45 status_t error = B_OK; 46 if (init_counter++ == 0) { 47 // open the file 48 #if DEBUG_PRINT 49 out = open(DEBUG_PRINT_FILE, O_RDWR | O_CREAT | O_TRUNC); 50 if (out < 0) { 51 error = errno; 52 init_counter--; 53 } 54 #endif // DEBUG_PRINT 55 // allocate the semaphore 56 if (error == B_OK) { 57 dbg_printf_sem = create_sem(1, "dbg_printf"); 58 if (dbg_printf_sem < 0) 59 error = dbg_printf_sem; 60 } 61 if (error == B_OK) { 62 #if DEBUG 63 __out("##################################################\n"); 64 #endif 65 } else 66 exit_debugging(); 67 } 68 return error; 69} 70 71 72status_t 73exit_debugging() 74{ 75 status_t error = B_OK; 76 if (--init_counter == 0) { 77 #if DEBUG_PRINT 78 close(out); 79 out = -1; 80 #endif // DEBUG_PRINT 81 delete_sem(dbg_printf_sem); 82 } else 83 error = B_NO_INIT; 84 return error; 85} 86 87 88static inline bool 89dbg_printf_lock() 90{ 91 thread_id thread = find_thread(NULL); 92 if (thread != dbg_printf_thread) { 93 if (acquire_sem(dbg_printf_sem) != B_OK) 94 return false; 95 dbg_printf_thread = thread; 96 } 97 dbg_printf_nesting++; 98 return true; 99} 100 101 102static inline void 103dbg_printf_unlock() 104{ 105 thread_id thread = find_thread(NULL); 106 if (thread != dbg_printf_thread) 107 return; 108 dbg_printf_nesting--; 109 if (dbg_printf_nesting == 0) { 110 dbg_printf_thread = -1; 111 release_sem(dbg_printf_sem); 112 } 113} 114 115#else 116 117status_t 118init_debugging() 119{ 120 status_t error = B_OK; 121 return error; 122} 123status_t 124exit_debugging() 125{ 126 status_t error = B_OK; 127 return error; 128} 129static inline bool 130dbg_printf_lock() 131{ 132 return true; 133} 134static inline void 135dbg_printf_unlock(){} 136 137#endif 138 139 140void 141dbg_printf_begin() 142{ 143 dbg_printf_lock(); 144} 145 146 147void 148dbg_printf_end() 149{ 150 dbg_printf_unlock(); 151} 152 153 154#if DEBUG_PRINT 155 156 157void 158dbg_vprintf(const char* format, va_list args) 159{ 160 if (!dbg_printf_lock()) 161 return; 162 163 char buffer[1024]; 164 vsnprintf(buffer, sizeof(buffer) - 1, format, args); 165 write(out, buffer, strlen(buffer)); 166 167 dbg_printf_unlock(); 168} 169 170 171void 172dbg_printf(const char* format,...) 173{ 174 va_list args; 175 va_start(args, format); 176 dbg_vprintf(format, args); 177 va_end(args); 178} 179 180 181#endif // DEBUG_PRINT 182