Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2822 → Rev 2823

/branches/tracing/kernel/generic/src/udebug/udebug_ipc.c
17,17 → 17,50
#include <udebug/udebug.h>
#include <udebug/udebug_ipc.h>
 
/**
* Get and lock a phone's callee task.
*
* This will return a pointer to the task to which the phone
* is connected. It will lock the task, making sure it exists.
* (TODO: make sure the udebug-cleanup of the task hasn't
* started yet)
*/
static task_t *get_lock_callee_task(phone_t *phone)
{
answerbox_t *answerbox;
answerbox_t *box;
task_t *ta;
task_id_t taskid;
ipl_t ipl;
 
// FIXME: locking!!!
ipl = interrupts_disable();
spinlock_lock(&phone->lock);
if (phone->state != IPC_PHONE_CONNECTED) {
spinlock_unlock(&phone->lock);
interrupts_restore(ipl);
return NULL;
}
 
answerbox = phone->callee;
ta = answerbox->task;
box = phone->callee;
spinlock_lock(&box->lock);
ta = box->task;
taskid = ta->taskid;
spinlock_unlock(&box->lock);
spinlock_unlock(&phone->lock);
 
/* Locking decoupled using taskid */
spinlock_lock(&tasks_lock);
ta = task_find_by_id(taskid);
if (ta == NULL) {
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
return NULL;
}
 
spinlock_lock(&ta->lock);
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
return ta;
}
35,14 → 68,17
static int udebug_rp_begin(call_t *call, phone_t *phone)
{
task_t *ta;
ipl_t ipl;
 
klog_printf("debug_begin()");
 
ipl = interrupts_disable();
ta = get_lock_callee_task(phone);
klog_printf("debugging task %llu", ta->taskid);
 
if (ta->being_debugged != false) {
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
klog_printf("debug_begin(): busy error");
return EBUSY;
}
55,11 → 91,13
ta->debug_begin_call = NULL;
ta->stop_request = false;
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
klog_printf("debug_begin(): immediate backsend");
return 1; /* actually we need backsend with 0 retval */
}
 
spinlock_unlock(&ta->lock);
interrupts_restore(ipl);
 
klog_printf("debug_begin() done (wait for stoppability)");
return 0;
69,6 → 107,7
{
thread_t *t;
task_t *ta;
ipl_t ipl;
 
klog_printf("debug_go()");
ta = get_lock_callee_task(phone);
75,17 → 114,22
 
// FIXME: must save this in thread struct, not task struct!!!
ta->debug_go_call = call;
spinlock_unlock(&ta->lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
if (!thread_exists(t)) {
spinlock_unlock(&ta->lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
klog_printf("debug_go(): waitq_wakeup");
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
 
spinlock_unlock(&ta->lock);
 
return 0; /* no backsend */
}
 
96,6 → 140,7
void *uspace_buffer;
unative_t to_copy;
int rc;
ipl_t ipl;
 
klog_printf("debug_args_read()");
// FIXME: verify task/thread state
102,12 → 147,23
 
ta = get_lock_callee_task(phone);
klog_printf("task %llu", ta->taskid);
spinlock_unlock(&ta->lock);
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
if (!thread_exists(t)) {
spinlock_unlock(&ta->lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
// FIXME: copy to a local buffer before releasing the lock
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
 
uspace_buffer = (void *)IPC_GET_ARG3(call->data);
to_copy = IPC_GET_ARG4(call->data);
if (to_copy > 6 * sizeof(unative_t)) to_copy = 6 * sizeof(unative_t);
119,8 → 175,6
return rc;
}
 
spinlock_unlock(&ta->lock);
 
IPC_SET_ARG1(call->data, to_copy);
 
klog_printf("debug_args_read() done");
/branches/tracing/kernel/generic/src/udebug/udebug.c
16,7 → 16,9
{
int nsc;
call_t *db_call;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
 
nsc = --TASK->not_stoppable_count;
31,6 → 33,7
TASK->stop_request = false;
TASK->debug_begin_call = NULL;
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
 
IPC_SET_RETVAL(db_call->data, 0);
klog_printf("udebug_stoppable_begin/ipc_answer");
37,17 → 40,23
ipc_answer(&TASK->answerbox, db_call);
} else {
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
}
 
void udebug_stoppable_end(void)
{
ipl_t ipl;
 
restart:
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
 
if (TASK->stop_request) {
TASK->debug_begin_call = NULL;
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
 
klog_printf("udebug_stoppable_end: waitq_sleep");
waitq_sleep(&THREAD->go_wq);
goto restart;
55,6 → 64,7
} else {
++TASK->not_stoppable_count;
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
}
 
62,10 → 72,13
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc)
{
call_t *call;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
 
/* being debugged + have go */
if (TASK->being_debugged && !TASK->stop_request) { /* locking! */
if (TASK->being_debugged && !TASK->stop_request) {
klog_printf("udebug_syscall_event");
call = TASK->debug_go_call;
IPC_SET_RETVAL(call->data, 0);
83,9 → 96,12
 
ipc_answer(&TASK->answerbox, TASK->debug_go_call);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
 
waitq_sleep(&THREAD->go_wq);
} else {
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
}