1 // Debug.cpp 2 // 3 // Copyright (c) 2003-2004, Ingo Weinhold (bonefish@cs.tu-berlin.de) 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a 6 // copy of this software and associated documentation files (the "Software"), 7 // to deal in the Software without restriction, including without limitation 8 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 // and/or sell copies of the Software, and to permit persons to whom the 10 // Software is furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 // DEALINGS IN THE SOFTWARE. 22 // 23 // Except as contained in this notice, the name of a copyright holder shall 24 // not be used in advertising or otherwise to promote the sale, use or other 25 // dealings in this Software without prior written authorization of the 26 // copyright holder. 27 28 #include <errno.h> 29 #include <fcntl.h> 30 #include <stdarg.h> 31 #include <stdio.h> 32 #include <string.h> 33 #include <unistd.h> 34 35 #include <OS.h> 36 37 #include "Debug.h" 38 39 /*! 40 \file Debug.cpp 41 \brief Defines debug output function with printf() signature printing 42 into a file. 43 44 \note The initialization is not thread safe! 45 */ 46 47 // locking support 48 static int32 init_counter = 0; 49 static sem_id dbg_printf_sem = -1; 50 static thread_id dbg_printf_thread = -1; 51 static int dbg_printf_nesting = 0; 52 53 #if DEBUG_PRINT 54 static int out = -1; 55 #endif 56 57 // init_debugging 58 status_t 59 init_debugging() 60 { 61 status_t error = B_OK; 62 if (init_counter++ == 0) { 63 // open the file 64 #if DEBUG_PRINT 65 out = open(DEBUG_PRINT_FILE, O_RDWR | O_CREAT | O_TRUNC); 66 if (out < 0) { 67 error = errno; 68 init_counter--; 69 } 70 #endif // DEBUG_PRINT 71 // allocate the semaphore 72 if (error == B_OK) { 73 dbg_printf_sem = create_sem(1, "dbg_printf"); 74 if (dbg_printf_sem < 0) 75 error = dbg_printf_sem; 76 } 77 if (error == B_OK) { 78 #if DEBUG 79 __out("##################################################\n"); 80 #endif 81 } else 82 exit_debugging(); 83 } 84 return error; 85 } 86 87 // exit_debugging 88 status_t 89 exit_debugging() 90 { 91 status_t error = B_OK; 92 if (--init_counter == 0) { 93 #if DEBUG_PRINT 94 close(out); 95 out = -1; 96 #endif // DEBUG_PRINT 97 delete_sem(dbg_printf_sem); 98 } else 99 error = B_NO_INIT; 100 return error; 101 } 102 103 // dbg_printf_lock 104 static inline 105 bool 106 dbg_printf_lock() 107 { 108 thread_id thread = find_thread(NULL); 109 if (thread != dbg_printf_thread) { 110 if (acquire_sem(dbg_printf_sem) != B_OK) 111 return false; 112 dbg_printf_thread = thread; 113 } 114 dbg_printf_nesting++; 115 return true; 116 } 117 118 // dbg_printf_unlock 119 static inline 120 void 121 dbg_printf_unlock() 122 { 123 thread_id thread = find_thread(NULL); 124 if (thread != dbg_printf_thread) 125 return; 126 dbg_printf_nesting--; 127 if (dbg_printf_nesting == 0) { 128 dbg_printf_thread = -1; 129 release_sem(dbg_printf_sem); 130 } 131 } 132 133 // dbg_printf_begin 134 void 135 dbg_printf_begin() 136 { 137 dbg_printf_lock(); 138 } 139 140 // dbg_printf_end 141 void 142 dbg_printf_end() 143 { 144 dbg_printf_unlock(); 145 } 146 147 #if DEBUG_PRINT 148 149 // dbg_printf 150 void 151 dbg_printf(const char *format,...) 152 { 153 if (!dbg_printf_lock()) 154 return; 155 char buffer[1024]; 156 va_list args; 157 va_start(args, format); 158 // no vsnprintf() on PPC and in kernel 159 #if defined(__INTEL__) && USER 160 vsnprintf(buffer, sizeof(buffer) - 1, format, args); 161 #else 162 vsprintf(buffer, format, args); 163 #endif 164 va_end(args); 165 buffer[sizeof(buffer) - 1] = '\0'; 166 write(out, buffer, strlen(buffer)); 167 dbg_printf_unlock(); 168 } 169 170 #endif // DEBUG_PRINT 171