Rev 2894 | Rev 2899 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2894 | Rev 2898 | ||
|---|---|---|---|
| Line 42... | Line 42... | ||
| 42 | #include <arch.h> |
42 | #include <arch.h> |
| 43 | 43 | ||
| 44 | void udebug_stoppable_begin(void) |
44 | void udebug_stoppable_begin(void) |
| 45 | { |
45 | { |
| 46 | int nsc; |
46 | int nsc; |
| 47 | call_t *db_call; |
47 | call_t *db_call, *go_call; |
| 48 | ipl_t ipl; |
48 | ipl_t ipl; |
| 49 | 49 | ||
| 50 | ipl = interrupts_disable(); |
50 | ipl = interrupts_disable(); |
| 51 | spinlock_lock(&TASK->lock); |
51 | spinlock_lock(&TASK->lock); |
| 52 | 52 | ||
| Line 57... | Line 57... | ||
| 57 | klog_printf("udebug_stoppable_begin"); |
57 | klog_printf("udebug_stoppable_begin"); |
| 58 | klog_printf(" - nsc := %d", nsc); |
58 | klog_printf(" - nsc := %d", nsc); |
| 59 | } |
59 | } |
| 60 | 60 | ||
| 61 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
61 | if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
| - | 62 | /* |
|
| - | 63 | * This was the last non-stoppable thread. Reply to |
|
| - | 64 | * DEBUG_BEGIN call. |
|
| - | 65 | */ |
|
| - | 66 | ||
| - | 67 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
| - | 68 | spinlock_lock(&THREAD->debug_lock); |
|
| - | 69 | THREAD->debug_stoppable = true; |
|
| - | 70 | spinlock_unlock(&THREAD->debug_lock); |
|
| - | 71 | ||
| 62 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
72 | TASK->dt_state = UDEBUG_TS_ACTIVE; |
| 63 | TASK->debug_begin_call = NULL; |
73 | TASK->debug_begin_call = NULL; |
| 64 | spinlock_unlock(&TASK->lock); |
74 | spinlock_unlock(&TASK->lock); |
| 65 | interrupts_restore(ipl); |
75 | interrupts_restore(ipl); |
| 66 | 76 | ||
| 67 | IPC_SET_RETVAL(db_call->data, 0); |
77 | IPC_SET_RETVAL(db_call->data, 0); |
| 68 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
78 | klog_printf("udebug_stoppable_begin/ipc_answer"); |
| 69 | ipc_answer(&TASK->answerbox, db_call); |
79 | ipc_answer(&TASK->answerbox, db_call); |
| - | 80 | ||
| - | 81 | } else if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
|
| - | 82 | /* |
|
| - | 83 | * Active debugging session |
|
| - | 84 | */ |
|
| - | 85 | ||
| - | 86 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
| - | 87 | spinlock_lock(&THREAD->debug_lock); |
|
| - | 88 | THREAD->debug_stoppable = true; |
|
| - | 89 | ||
| - | 90 | if (THREAD->debug_stop) { |
|
| - | 91 | /* |
|
| - | 92 | * Thread was requested to stop - answer go call |
|
| - | 93 | */ |
|
| - | 94 | ||
| - | 95 | /* Make sure nobody takes this call away from us */ |
|
| - | 96 | go_call = THREAD->debug_go_call; |
|
| - | 97 | THREAD->debug_go_call = NULL; |
|
| - | 98 | ||
| - | 99 | IPC_SET_RETVAL(go_call->data, 0); |
|
| - | 100 | IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP); |
|
| - | 101 | ||
| - | 102 | THREAD->cur_event = UDEBUG_EVENT_STOP; |
|
| - | 103 | spinlock_unlock(&THREAD->debug_lock); |
|
| - | 104 | ||
| - | 105 | ipc_answer(&TASK->answerbox, go_call); |
|
| - | 106 | ||
| - | 107 | spinlock_unlock(&TASK->lock); |
|
| - | 108 | interrupts_restore(ipl); |
|
| - | 109 | } else { |
|
| - | 110 | /* |
|
| - | 111 | * No stop request - nothing happens. |
|
| - | 112 | */ |
|
| - | 113 | spinlock_unlock(&THREAD->debug_lock); |
|
| - | 114 | spinlock_unlock(&TASK->lock); |
|
| - | 115 | interrupts_restore(ipl); |
|
| - | 116 | } |
|
| 70 | } else { |
117 | } else { |
| - | 118 | /* |
|
| - | 119 | * All other cases - nothing special happens. |
|
| - | 120 | */ |
|
| - | 121 | ||
| - | 122 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
| - | 123 | spinlock_lock(&THREAD->debug_lock); |
|
| - | 124 | THREAD->debug_stoppable = true; |
|
| - | 125 | spinlock_unlock(&THREAD->debug_lock); |
|
| - | 126 | ||
| 71 | spinlock_unlock(&TASK->lock); |
127 | spinlock_unlock(&TASK->lock); |
| 72 | interrupts_restore(ipl); |
128 | interrupts_restore(ipl); |
| 73 | } |
129 | } |
| 74 | } |
130 | } |
| 75 | 131 | ||
| Line 79... | Line 135... | ||
| 79 | 135 | ||
| 80 | restart: |
136 | restart: |
| 81 | ipl = interrupts_disable(); |
137 | ipl = interrupts_disable(); |
| 82 | spinlock_lock(&TASK->lock); |
138 | spinlock_lock(&TASK->lock); |
| 83 | 139 | ||
| - | 140 | /* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
|
| - | 141 | spinlock_lock(&THREAD->debug_lock); |
|
| - | 142 | ||
| - | 143 | if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
|
| - | 144 | klog_printf("udebug_stoppable_end"); |
|
| - | 145 | klog_printf("debug_stop=%d", THREAD->debug_stop); |
|
| - | 146 | } |
|
| - | 147 | ||
| 84 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
148 | if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
| 85 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
149 | TASK->dt_state == UDEBUG_TS_ACTIVE) && |
| 86 | THREAD->debug_stop == true) { |
150 | THREAD->debug_stop == true) { |
| 87 | TASK->debug_begin_call = NULL; |
151 | TASK->debug_begin_call = NULL; |
| - | 152 | spinlock_unlock(&THREAD->debug_lock); |
|
| 88 | spinlock_unlock(&TASK->lock); |
153 | spinlock_unlock(&TASK->lock); |
| 89 | interrupts_restore(ipl); |
154 | interrupts_restore(ipl); |
| 90 | 155 | ||
| 91 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
156 | klog_printf("udebug_stoppable_end: waitq_sleep"); |
| 92 | waitq_sleep(&THREAD->go_wq); |
157 | waitq_sleep(&THREAD->go_wq); |
| 93 | goto restart; |
158 | goto restart; |
| 94 | /* must try again - have to lose stoppability atomically */ |
159 | /* must try again - have to lose stoppability atomically */ |
| 95 | } else { |
160 | } else { |
| 96 | ++TASK->not_stoppable_count; |
161 | ++TASK->not_stoppable_count; |
| - | 162 | THREAD->debug_stoppable = false; |
|
| - | 163 | ||
| - | 164 | spinlock_unlock(&THREAD->debug_lock); |
|
| 97 | spinlock_unlock(&TASK->lock); |
165 | spinlock_unlock(&TASK->lock); |
| 98 | interrupts_restore(ipl); |
166 | interrupts_restore(ipl); |
| 99 | } |
167 | } |
| 100 | } |
168 | } |
| 101 | 169 | ||