44,7 → 44,7 |
void udebug_stoppable_begin(void) |
{ |
int nsc; |
call_t *db_call; |
call_t *db_call, *go_call; |
ipl_t ipl; |
|
ipl = interrupts_disable(); |
59,6 → 59,16 |
} |
|
if (TASK->dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
/* |
* This was the last non-stoppable thread. Reply to |
* DEBUG_BEGIN call. |
*/ |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
spinlock_unlock(&THREAD->debug_lock); |
|
TASK->dt_state = UDEBUG_TS_ACTIVE; |
TASK->debug_begin_call = NULL; |
spinlock_unlock(&TASK->lock); |
67,7 → 77,53 |
IPC_SET_RETVAL(db_call->data, 0); |
klog_printf("udebug_stoppable_begin/ipc_answer"); |
ipc_answer(&TASK->answerbox, db_call); |
|
} else if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
/* |
* Active debugging session |
*/ |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
|
if (THREAD->debug_stop) { |
/* |
* Thread was requested to stop - answer go call |
*/ |
|
/* Make sure nobody takes this call away from us */ |
go_call = THREAD->debug_go_call; |
THREAD->debug_go_call = NULL; |
|
IPC_SET_RETVAL(go_call->data, 0); |
IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP); |
|
THREAD->cur_event = UDEBUG_EVENT_STOP; |
spinlock_unlock(&THREAD->debug_lock); |
|
ipc_answer(&TASK->answerbox, go_call); |
|
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} else { |
/* |
* No stop request - nothing happens. |
*/ |
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
} else { |
/* |
* All other cases - nothing special happens. |
*/ |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
spinlock_lock(&THREAD->debug_lock); |
THREAD->debug_stoppable = true; |
spinlock_unlock(&THREAD->debug_lock); |
|
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |
81,10 → 137,19 |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
|
/* Lock order OK, THREAD->debug_lock is after TASK->lock */ |
spinlock_lock(&THREAD->debug_lock); |
|
if (TASK->dt_state == UDEBUG_TS_ACTIVE) { |
klog_printf("udebug_stoppable_end"); |
klog_printf("debug_stop=%d", THREAD->debug_stop); |
} |
|
if ((TASK->dt_state == UDEBUG_TS_BEGINNING || |
TASK->dt_state == UDEBUG_TS_ACTIVE) && |
THREAD->debug_stop == true) { |
TASK->debug_begin_call = NULL; |
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
|
94,6 → 159,9 |
/* must try again - have to lose stoppability atomically */ |
} else { |
++TASK->not_stoppable_count; |
THREAD->debug_stoppable = false; |
|
spinlock_unlock(&THREAD->debug_lock); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
} |