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 31 static int32 init_counter = 0; 32 static sem_id dbg_printf_sem = -1; 33 static thread_id dbg_printf_thread = -1; 34 static int dbg_printf_nesting = 0; 35 36 37 #if DEBUG_PRINT 38 static int out = -1; 39 #endif 40 41 42 status_t 43 init_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 72 status_t 73 exit_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 88 static inline bool 89 dbg_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 102 static inline void 103 dbg_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 117 status_t 118 init_debugging() 119 { 120 status_t error = B_OK; 121 return error; 122 } 123 status_t 124 exit_debugging() 125 { 126 status_t error = B_OK; 127 return error; 128 } 129 static inline bool 130 dbg_printf_lock() 131 { 132 return true; 133 } 134 static inline void 135 dbg_printf_unlock(){} 136 137 #endif 138 139 140 void 141 dbg_printf_begin() 142 { 143 dbg_printf_lock(); 144 } 145 146 147 void 148 dbg_printf_end() 149 { 150 dbg_printf_unlock(); 151 } 152 153 154 #if DEBUG_PRINT 155 156 157 void 158 dbg_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 171 void 172 dbg_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