Rev 3030 | Rev 3032 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3030 | Rev 3031 | ||
|---|---|---|---|
| Line 31... | Line 31... | ||
| 31 | */ |
31 | */ |
| 32 | 32 | ||
| 33 | /** |
33 | /** |
| 34 | * @file |
34 | * @file |
| 35 | * @brief Udebug. |
35 | * @brief Udebug. |
| - | 36 | * |
|
| - | 37 | * Functions in this file are executed directly in each thread, which |
|
| - | 38 | * may or may not be the subject of debugging. The udebug_stoppable_begin/end() |
|
| - | 39 | * functions are also executed in the clock interrupt handler. To avoid |
|
| - | 40 | * deadlock, functions in this file are protected from the interrupt |
|
| - | 41 | * by locking the recursive lock THREAD->udebug.int_lock (just an atomic |
|
| - | 42 | * variable). This prevents udebug_stoppable_begin/end() from being |
|
| - | 43 | * executed in the interrupt handler (they are skipped). |
|
| - | 44 | * |
|
| - | 45 | * Functions in udebug_ops.c and udebug_ipc.c execute in different threads, |
|
| - | 46 | * so they needn't be protected from the (preemptible) interrupt-initiated |
|
| - | 47 | * code. |
|
| 36 | */ |
48 | */ |
| 37 | 49 | ||
| 38 | #include <synch/waitq.h> |
50 | #include <synch/waitq.h> |
| 39 | #include <console/klog.h> |
51 | #include <console/klog.h> |
| 40 | #include <udebug/udebug.h> |
52 | #include <udebug/udebug.h> |
| 41 | #include <errno.h> |
53 | #include <errno.h> |
| 42 | #include <arch.h> |
54 | #include <arch.h> |
| 43 | 55 | ||
| 44 | /* |
- | |
| 45 | * FIXME: Don't grab TASK->udebug.lock in this module, synchronize |
- | |
| 46 | * only with THREAD->udebug.lock. |
- | |
| 47 | * |
- | |
| 48 | * For this reason, TASK->udebug.lock is not guarded against the interrupt |
- | |
| 49 | * handler in udebug_ops.c. (which could deadlock) |
- | |
| 50 | */ |
- | |
| 51 | - | ||
| 52 | static inline void udebug_int_lock(void) |
56 | static inline void udebug_int_lock(void) |
| 53 | { |
57 | { |
| 54 | atomic_inc(&THREAD->udebug.int_lock); |
58 | atomic_inc(&THREAD->udebug.int_lock); |
| 55 | } |
59 | } |
| 56 | 60 | ||
| Line 228... | Line 232... | ||
| 228 | mutex_lock(&TASK->udebug.lock); |
232 | mutex_lock(&TASK->udebug.lock); |
| 229 | 233 | ||
| 230 | /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
234 | /* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
| 231 | mutex_lock(&THREAD->udebug.lock); |
235 | mutex_lock(&THREAD->udebug.lock); |
| 232 | 236 | ||
| 233 | if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
- | |
| 234 | //klog_printf("udebug_stoppable_end"); |
- | |
| 235 | //klog_printf("udebug.stop=%d", THREAD->udebug.stop); |
- | |
| 236 | } |
- | |
| 237 | - | ||
| 238 | if (THREAD->udebug.debug_active && |
237 | if (THREAD->udebug.debug_active && |
| 239 | THREAD->udebug.stop == true) { |
238 | THREAD->udebug.stop == true) { |
| 240 | TASK->udebug.begin_call = NULL; |
239 | TASK->udebug.begin_call = NULL; |
| 241 | mutex_unlock(&THREAD->udebug.lock); |
240 | mutex_unlock(&THREAD->udebug.lock); |
| 242 | mutex_unlock(&TASK->udebug.lock); |
241 | mutex_unlock(&TASK->udebug.lock); |