Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2897 → Rev 2898

/branches/tracing/kernel/generic/src/udebug/udebug_ops.c
52,9 → 52,10
* but only if it verifies all conditions.
*
* Specifically, verifies that thread t exists, is a userspace thread,
* and belongs to the current task (TASK). It also locks t->debug_lock,
* making sure that t->debug_active is true - that the thread is
* in a valid debugging session.
* and belongs to the current task (TASK). Verifies, that the thread
* has (or hasn't) go according to having_go (typically false).
* It also locks t->debug_lock, making sure that t->debug_active is true
* - that the thread is in a valid debugging session.
*
* Returns EOK if all went well, or an error code otherwise.
* Interrupts must be already disabled when calling this function.
61,7 → 62,7
*
* Note: This function sports complicated locking.
*/
static int _thread_op_begin(thread_t *t)
static int _thread_op_begin(thread_t *t, bool having_go)
{
int rc;
task_id_t taskid;
93,9 → 94,9
goto error_exit;
}
 
if ((t->debug_active != true) || (t->debug_stop != true)) {
/* Not in debugging session or already has GO */
rc = ENOENT;
if ((t->debug_active != true) || (!t->debug_stop != having_go)) {
/* Not in debugging session or undesired GO state */
rc = EINVAL;
goto error_exit;
}
 
213,7 → 214,7
ipl = interrupts_disable();
 
/* On success, this will lock t->debug_lock */
rc = _thread_op_begin(t);
rc = _thread_op_begin(t, false);
if (rc != EOK) {
interrupts_restore(ipl);
return rc;
234,7 → 235,60
return 0;
}
 
int udebug_stop(thread_t *t, call_t *call)
{
ipl_t ipl;
int rc;
 
klog_printf("udebug_stop()");
 
ipl = interrupts_disable();
 
/*
* On success, this will lock t->debug_lock. Note that this makes sure
* the thread is not stopped.
*/
rc = _thread_op_begin(t, true);
if (rc != EOK) {
interrupts_restore(ipl);
return rc;
}
 
/* Take GO away from the thread */
t->debug_stop = true;
 
if (!t->debug_stoppable) {
/* Answer will be sent when the thread becomes stoppable */
_thread_op_end(t);
interrupts_restore(ipl);
return 0;
}
 
/*
* Answer GO call
*/
klog_printf("udebug_stop - answering go call");
 
/* Make sure nobody takes this call away from us */
call = t->debug_go_call;
t->debug_go_call = NULL;
 
IPC_SET_RETVAL(call->data, 0);
IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
klog_printf("udebug_stop/ipc_answer");
 
THREAD->cur_event = UDEBUG_EVENT_STOP;
_thread_op_end(t);
 
spinlock_lock(&TASK->lock);
ipc_answer(&TASK->answerbox, call);
spinlock_unlock(&TASK->lock);
 
interrupts_restore(ipl);
klog_printf("udebog_stop/done");
return 0;
}
 
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
{
thread_t *t;
310,7 → 364,7
ipl = interrupts_disable();
 
/* On success, this will lock t->debug_lock */
rc = _thread_op_begin(t);
rc = _thread_op_begin(t, false);
if (rc != EOK) {
interrupts_restore(ipl);
return rc;
350,7 → 404,7
ipl = interrupts_disable();
 
/* On success, this will lock t->debug_lock */
rc = _thread_op_begin(t);
rc = _thread_op_begin(t, false);
if (rc != EOK) {
interrupts_restore(ipl);
return rc;
389,7 → 443,7
ipl = interrupts_disable();
 
/* On success, this will lock t->debug_lock */
rc = _thread_op_begin(t);
rc = _thread_op_begin(t, false);
if (rc != EOK) {
interrupts_restore(ipl);
return rc;