// Debug.cpp // // Copyright (c) 2003-2004, Ingo Weinhold (bonefish@cs.tu-berlin.de) // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // // Except as contained in this notice, the name of a copyright holder shall // not be used in advertising or otherwise to promote the sale, use or other // dealings in this Software without prior written authorization of the // copyright holder. #include #include #include #include #include #include #include #include "Debug.h" /*! \file Debug.cpp \brief Defines debug output function with printf() signature printing into a file. \note The initialization is not thread safe! */ // locking support static int32 init_counter = 0; static sem_id dbg_printf_sem = -1; static thread_id dbg_printf_thread = -1; static int dbg_printf_nesting = 0; #if DEBUG_PRINT static int out = -1; #endif // init_debugging status_t init_debugging() { status_t error = B_OK; if (init_counter++ == 0) { // open the file #if DEBUG_PRINT out = open(DEBUG_PRINT_FILE, O_RDWR | O_CREAT | O_TRUNC); if (out < 0) { error = errno; init_counter--; } #endif // DEBUG_PRINT // allocate the semaphore if (error == B_OK) { dbg_printf_sem = create_sem(1, "dbg_printf"); if (dbg_printf_sem < 0) error = dbg_printf_sem; } if (error == B_OK) { #if DEBUG __out("##################################################\n"); #endif } else exit_debugging(); } return error; } // exit_debugging status_t exit_debugging() { status_t error = B_OK; if (--init_counter == 0) { #if DEBUG_PRINT close(out); out = -1; #endif // DEBUG_PRINT delete_sem(dbg_printf_sem); } else error = B_NO_INIT; return error; } // dbg_printf_lock static inline bool dbg_printf_lock() { thread_id thread = find_thread(NULL); if (thread != dbg_printf_thread) { if (acquire_sem(dbg_printf_sem) != B_OK) return false; dbg_printf_thread = thread; } dbg_printf_nesting++; return true; } // dbg_printf_unlock static inline void dbg_printf_unlock() { thread_id thread = find_thread(NULL); if (thread != dbg_printf_thread) return; dbg_printf_nesting--; if (dbg_printf_nesting == 0) { dbg_printf_thread = -1; release_sem(dbg_printf_sem); } } // dbg_printf_begin void dbg_printf_begin() { dbg_printf_lock(); } // dbg_printf_end void dbg_printf_end() { dbg_printf_unlock(); } #if DEBUG_PRINT // dbg_printf void dbg_printf(const char *format,...) { if (!dbg_printf_lock()) return; char buffer[1024]; va_list args; va_start(args, format); // no vsnprintf() on PPC and in kernel #if defined(__INTEL__) && USER vsnprintf(buffer, sizeof(buffer) - 1, format, args); #else vsprintf(buffer, format, args); #endif va_end(args); buffer[sizeof(buffer) - 1] = '\0'; write(out, buffer, strlen(buffer)); dbg_printf_unlock(); } #endif // DEBUG_PRINT