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