33,6 → 33,18 |
/** |
* @file |
* @brief Udebug. |
* |
* Functions in this file are executed directly in each thread, which |
* may or may not be the subject of debugging. The udebug_stoppable_begin/end() |
* functions are also executed in the clock interrupt handler. To avoid |
* deadlock, functions in this file are protected from the interrupt |
* by locking the recursive lock THREAD->udebug.int_lock (just an atomic |
* variable). This prevents udebug_stoppable_begin/end() from being |
* executed in the interrupt handler (they are skipped). |
* |
* Functions in udebug_ops.c and udebug_ipc.c execute in different threads, |
* so they needn't be protected from the (preemptible) interrupt-initiated |
* code. |
*/ |
|
#include <synch/waitq.h> |
41,14 → 53,6 |
#include <errno.h> |
#include <arch.h> |
|
/* |
* FIXME: Don't grab TASK->udebug.lock in this module, synchronize |
* only with THREAD->udebug.lock. |
* |
* For this reason, TASK->udebug.lock is not guarded against the interrupt |
* handler in udebug_ops.c. (which could deadlock) |
*/ |
|
static inline void udebug_int_lock(void) |
{ |
atomic_inc(&THREAD->udebug.int_lock); |
230,11 → 234,6 |
/* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
mutex_lock(&THREAD->udebug.lock); |
|
if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
//klog_printf("udebug_stoppable_end"); |
//klog_printf("udebug.stop=%d", THREAD->udebug.stop); |
} |
|
if (THREAD->udebug.debug_active && |
THREAD->udebug.stop == true) { |
TASK->udebug.begin_call = NULL; |