118,6 → 118,77 |
return rc; |
} |
|
static int udebug_rp_end(call_t *call, phone_t *phone) |
{ |
task_t *ta; |
ipl_t ipl; |
|
thread_t *t; |
link_t *cur; |
|
klog_printf("udebug_rp_end()"); |
|
ipl = interrupts_disable(); |
ta = get_lock_callee_task(phone); |
klog_printf("task %llu", ta->taskid); |
|
//TODO: UDEBUG_TS_BEGINNING |
if (ta->dt_state != UDEBUG_TS_ACTIVE) { |
spinlock_unlock(&ta->lock); |
interrupts_restore(ipl); |
klog_printf("udebug_rp_begin(): task not in TS_BEGINNING"); |
return EINVAL; |
} |
|
/* Clear debug_active from all of the task's userspace threads */ |
|
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
t = list_get_instance(cur, thread_t, th_link); |
|
spinlock_lock(&t->lock); |
if ((t->flags & THREAD_FLAG_USPACE) != 0) |
t->debug_active = true; |
spinlock_unlock(&t->lock); |
} |
|
/* Now respond to unanswered GO calls and reset thread states */ |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
t = list_get_instance(cur, thread_t, th_link); |
|
spinlock_lock(&t->lock); |
|
/* Still has go? */ |
if ((t->flags & THREAD_FLAG_USPACE) != 0 && |
t->debug_stop == false) { |
/* |
* Yes, so clear go. As debug_active == false, |
* this doesn't affect anything. |
*/ |
t->debug_stop = true; |
|
/* Answer GO call */ |
ipc_answer(&ta->answerbox, t->debug_go_call); |
} else { |
/* |
* Debug_stop is already at initial value. |
* Yet this means the thread needs waking up. |
*/ |
waitq_wakeup(&t->go_wq, WAKEUP_FIRST); |
} |
spinlock_unlock(&t->lock); |
} |
|
ta->dt_state = UDEBUG_TS_INACTIVE; |
|
spinlock_unlock(&ta->lock); |
interrupts_restore(ipl); |
|
klog_printf("udebug_rp_end() done\n"); |
|
return 1; |
} |
|
|
static int udebug_rp_go(call_t *call, phone_t *phone) |
{ |
thread_t *t; |
473,6 → 544,9 |
case UDEBUG_M_BEGIN: |
rc = udebug_rp_begin(call, phone); |
return rc; |
case UDEBUG_M_END: |
rc = udebug_rp_end(call, phone); |
return rc; |
case UDEBUG_M_GO: |
rc = udebug_rp_go(call, phone); |
return rc; |