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 26static int32 init_counter = 0; 27static sem_id dbg_printf_sem = -1; 28static thread_id dbg_printf_thread = -1; 29static int dbg_printf_nesting = 0; 30 31#if DEBUG_PRINT 32static int out = -1; 33#endif 34 35// init_debugging 36status_t 37init_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 66status_t 67exit_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 82static inline 83bool 84dbg_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 97static inline 98void 99dbg_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 112void 113dbg_printf_begin() 114{ 115 dbg_printf_lock(); 116} 117 118// dbg_printf_end 119void 120dbg_printf_end() 121{ 122 dbg_printf_unlock(); 123} 124 125#if DEBUG_PRINT 126 127// dbg_printf 128void 129dbg_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