Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2847 → Rev 2848

/branches/tracing/kernel/generic/include/proc/thread.h
205,6 → 205,7
uint8_t *kstack;
 
/** Debugging stuff */
SPINLOCK_DECLARE(debug_lock);
waitq_t go_wq;
call_t *debug_go_call;
unative_t syscall_args[6];
/branches/tracing/kernel/generic/src/proc/thread.c
176,6 → 176,8
return -1;
}
 
spinlock_initialize(&t->debug_lock, "thread_debug_lock");
 
return 0;
}
 
/branches/tracing/kernel/generic/src/udebug/udebug_ipc.c
22,6 → 22,9
*
* This will return a pointer to the task to which the phone
* is connected. It will lock the task, making sure it exists.
*
* Interrupts must be already disabled.
*
* (TODO: make sure the udebug-cleanup of the task hasn't
* started yet)
*/
30,13 → 33,10
answerbox_t *box;
task_t *ta;
task_id_t taskid;
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&phone->lock);
if (phone->state != IPC_PHONE_CONNECTED) {
spinlock_unlock(&phone->lock);
interrupts_restore(ipl);
return NULL;
}
 
54,13 → 54,11
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;
}
132,10 → 130,10
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);
spinlock_lock(&t->debug_lock);
if ((t->flags & THREAD_FLAG_USPACE) != 0)
t->debug_active = true;
spinlock_unlock(&t->lock);
spinlock_unlock(&t->debug_lock);
}
 
spinlock_unlock(&ta->lock);
154,6 → 152,7
 
thread_t *t;
link_t *cur;
int flags;
 
klog_printf("udebug_rp_end()");
 
175,8 → 174,13
 
spinlock_lock(&t->lock);
 
flags = t->flags;
 
spinlock_lock(&t->debug_lock);
spinlock_unlock(&t->lock);
 
/* Only process userspace threads */
if ((t->flags & THREAD_FLAG_USPACE) != 0) {
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Prevent any further debug activity in thread */
t->debug_active = false;
 
198,11 → 202,15
* Debug_stop is already at initial value.
* Yet this means the thread needs waking up.
*/
 
/*
* t's lock must not be held when calling
* waitq_wakeup.
*/
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
}
}
 
spinlock_unlock(&t->lock);
spinlock_unlock(&t->debug_lock);
}
 
ta->dt_state = UDEBUG_TS_INACTIVE;
223,8 → 231,12
thread_t *t;
task_t *ta;
ipl_t ipl;
int rc;
 
klog_printf("debug_go()");
 
ipl = interrupts_disable();
 
ta = get_lock_callee_task(phone);
spinlock_unlock(&ta->lock);
// TODO: don't lock ta
231,15 → 243,40
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
if (!thread_exists(t)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&t->debug_lock);
 
/* Verify that thread t may be operated on */
rc = verify_thread(t, ta);
if (rc != EOK) {
spinlock_unlock(&t->debug_lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return rc;
}
 
/*
* Since t->debug_active == true and t->debug_lock is held,
* we can safely release threads_lock and t will continue
* to exist (and will stay in debug_active state)
*/
spinlock_unlock(&threads_lock);
 
t->debug_go_call = call;
t->debug_stop = false;
 
/*
* Neither t's lock nor threads_lock may be held during wakeup
*/
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
 
spinlock_unlock(&threads_lock);
spinlock_unlock(&t->debug_lock);
interrupts_restore(ipl);
 
return 0; /* no backsend */
256,6 → 293,7
 
klog_printf("debug_args_read()");
 
ipl = interrupts_disable();
ta = get_lock_callee_task(phone);
klog_printf("task %llu", ta->taskid);
spinlock_unlock(&ta->lock);
262,23 → 300,37
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
ipl = interrupts_disable();
spinlock_lock(&threads_lock);
 
/* Verify that thread t exists and may be operated on */
if (!thread_exists(t)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&t->debug_lock);
 
/* Verify that thread t may be operated on */
rc = verify_thread(t, ta);
if (rc != EOK) {
spinlock_unlock(&t->debug_lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return rc;
}
 
/*
* We can now safely release threads_lock as debug_active == true
* and t->debug_lock is held.
*/
spinlock_unlock(&threads_lock);
 
//FIXME: additionally we need to verify that we are inside a syscall
 
/* Copy to a local buffer before releasing the lock */
memcpy(buffer, t->syscall_args, 6 * sizeof(unative_t));
 
spinlock_unlock(&threads_lock);
spinlock_unlock(&t->debug_lock);
interrupts_restore(ipl);
 
/* Now copy to userspace */
318,14 → 370,29
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
/* Verify that thread t exists and may be operated on */
if (!thread_exists(t)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&t->debug_lock);
 
/* Verify that thread t may be operated on */
rc = verify_thread(t, ta);
if (rc != EOK) {
spinlock_unlock(&t->debug_lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return rc;
}
 
/*
* We can now safely release threads_lock as debug_active == true
* and t->debug_lock is held.
*/
spinlock_unlock(&threads_lock);
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
336,7 → 403,7
 
/* Copy to a local buffer so that we can release the lock */
memcpy(&state_copy, state, sizeof(state_copy));
spinlock_unlock(&threads_lock);
spinlock_unlock(&t->debug_lock);
interrupts_restore(ipl);
 
uspace_buffer = (void *)IPC_GET_ARG3(call->data);
345,7 → 412,6
 
rc = copy_to_uspace(uspace_buffer, &state_copy, to_copy);
if (rc != 0) {
spinlock_unlock(&ta->lock);
klog_printf("debug_regs_read() - copy failed");
return rc;
}
393,9 → 459,18
 
t = (thread_t *) IPC_GET_ARG2(call->data);
 
/* Verify that thread t exists and may be operated on */
if (!thread_exists(t)) {
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return ENOENT;
}
 
spinlock_lock(&t->debug_lock);
 
/* Verify that thread t may be operated on */
rc = verify_thread(t, ta);
if (rc != EOK) {
spinlock_unlock(&t->debug_lock);
spinlock_unlock(&threads_lock);
interrupts_restore(ipl);
return rc;
403,7 → 478,7
 
state = t->uspace_state;
if (state == NULL) {
spinlock_unlock(&threads_lock);
spinlock_unlock(&t->debug_lock);
interrupts_restore(ipl);
klog_printf("debug_regs_write() - istate not available");
return EBUSY;
411,7 → 486,7
 
memcpy(t->uspace_state, &data_copy, sizeof(t->uspace_state));
 
spinlock_unlock(&threads_lock);
spinlock_unlock(&t->debug_lock);
interrupts_restore(ipl);
 
/* Set answer values */
/branches/tracing/kernel/generic/src/udebug/udebug.c
77,7 → 77,7
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&THREAD->lock);
spinlock_lock(&THREAD->debug_lock);
 
if (THREAD->debug_active == true) {
klog_printf("udebug_syscall_event");
101,7 → 101,7
* point it must be back to the initial true value).
*/
THREAD->debug_stop = true;
spinlock_unlock(&THREAD->lock);
spinlock_unlock(&THREAD->debug_lock);
 
spinlock_lock(&TASK->lock);
ipc_answer(&TASK->answerbox, THREAD->debug_go_call);
111,7 → 111,7
 
waitq_sleep(&THREAD->go_wq);
} else {
spinlock_unlock(&THREAD->lock);
spinlock_unlock(&THREAD->debug_lock);
interrupts_restore(ipl);
}
}