Rev 2867 | Rev 2894 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2867 | Rev 2870 | ||
---|---|---|---|
Line 8... | Line 8... | ||
8 | */ |
8 | */ |
9 | 9 | ||
10 | #include <synch/waitq.h> |
10 | #include <synch/waitq.h> |
11 | #include <console/klog.h> |
11 | #include <console/klog.h> |
12 | #include <udebug/udebug.h> |
12 | #include <udebug/udebug.h> |
- | 13 | #include <errno.h> |
|
13 | #include <arch.h> |
14 | #include <arch.h> |
14 | 15 | ||
15 | void udebug_stoppable_begin(void) |
16 | void udebug_stoppable_begin(void) |
16 | { |
17 | { |
17 | int nsc; |
18 | int nsc; |
Line 167... | Line 168... | ||
167 | klog_printf("- sleep"); |
168 | klog_printf("- sleep"); |
168 | 169 | ||
169 | waitq_sleep(&THREAD->go_wq); |
170 | waitq_sleep(&THREAD->go_wq); |
170 | } |
171 | } |
171 | 172 | ||
- | 173 | /** |
|
- | 174 | * Terminate task debugging session. |
|
- | 175 | * |
|
- | 176 | * \param ta Must be already locked and interrupts must be disabled. |
|
- | 177 | * \return Zero on success or negative error code. |
|
- | 178 | */ |
|
- | 179 | int udebug_task_cleanup(struct task *ta) |
|
- | 180 | { |
|
- | 181 | thread_t *t; |
|
- | 182 | link_t *cur; |
|
- | 183 | int flags; |
|
- | 184 | ||
- | 185 | klog_printf("udebug_task_cleanup()"); |
|
- | 186 | klog_printf("task %llu", ta->taskid); |
|
- | 187 | ||
- | 188 | if (ta->dt_state == UDEBUG_TS_BEGINNING && |
|
- | 189 | ta->dt_state != UDEBUG_TS_ACTIVE) { |
|
- | 190 | klog_printf("udebug_task_cleanup(): task not being debugged"); |
|
- | 191 | return EINVAL; |
|
- | 192 | } |
|
- | 193 | ||
- | 194 | /* Finish debugging of all userspace threads */ |
|
- | 195 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
|
- | 196 | t = list_get_instance(cur, thread_t, th_link); |
|
- | 197 | ||
- | 198 | spinlock_lock(&t->debug_lock); |
|
- | 199 | spinlock_lock(&t->lock); |
|
- | 200 | ||
- | 201 | flags = t->flags; |
|
- | 202 | ||
- | 203 | spinlock_unlock(&t->lock); |
|
- | 204 | ||
- | 205 | /* Only process userspace threads */ |
|
- | 206 | if ((flags & THREAD_FLAG_USPACE) != 0) { |
|
- | 207 | /* Prevent any further debug activity in thread */ |
|
- | 208 | t->debug_active = false; |
|
- | 209 | t->cur_event = 0; /* none */ |
|
- | 210 | ||
- | 211 | /* Still has go? */ |
|
- | 212 | if (t->debug_stop == false) { |
|
- | 213 | /* |
|
- | 214 | * Yes, so clear go. As debug_active == false, |
|
- | 215 | * this doesn't affect anything. |
|
- | 216 | */ |
|
- | 217 | t->debug_stop = true; |
|
- | 218 | ||
- | 219 | /* Answer GO call */ |
|
- | 220 | klog_printf("answer GO call with EVENT_FINISHED"); |
|
- | 221 | IPC_SET_RETVAL(t->debug_go_call->data, 0); |
|
- | 222 | IPC_SET_ARG1(t->debug_go_call->data, UDEBUG_EVENT_FINISHED); |
|
- | 223 | ipc_answer(&ta->answerbox, t->debug_go_call); |
|
- | 224 | } else { |
|
- | 225 | /* |
|
- | 226 | * Debug_stop is already at initial value. |
|
- | 227 | * Yet this means the thread needs waking up. |
|
- | 228 | */ |
|
- | 229 | ||
- | 230 | /* |
|
- | 231 | * t's lock must not be held when calling |
|
- | 232 | * waitq_wakeup. |
|
- | 233 | */ |
|
- | 234 | waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
|
- | 235 | } |
|
- | 236 | } |
|
- | 237 | spinlock_unlock(&t->debug_lock); |
|
- | 238 | } |
|
- | 239 | ||
- | 240 | ta->dt_state = UDEBUG_TS_INACTIVE; |
|
- | 241 | ta->debugger = NULL; |
|
- | 242 | ||
- | 243 | return 0; |
|
- | 244 | } |
|
- | 245 | ||
172 | 246 | ||
173 | /** @} |
247 | /** @} |
174 | */ |
248 | */ |