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 48static int32 init_counter = 0; 49static sem_id dbg_printf_sem = -1; 50static thread_id dbg_printf_thread = -1; 51static int dbg_printf_nesting = 0; 52 53#if DEBUG_PRINT 54static int out = -1; 55#endif 56 57// init_debugging 58status_t 59init_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 88status_t 89exit_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 104static inline 105bool 106dbg_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 119static inline 120void 121dbg_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 134void 135dbg_printf_begin() 136{ 137 dbg_printf_lock(); 138} 139 140// dbg_printf_end 141void 142dbg_printf_end() 143{ 144 dbg_printf_unlock(); 145} 146 147#if DEBUG_PRINT 148 149// dbg_printf 150void 151dbg_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