Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2803 → Rev 2804

/branches/tracing/kernel/generic/include/proc/task.h
99,6 → 99,7
bool stop_request;
call_t *debug_begin_call;
call_t *debug_go_call;
int not_stoppable_count;
/** Architecture specific task data. */
task_arch_t arch;
/branches/tracing/kernel/generic/include/udebug.h
8,7 → 8,8
#define KERN_UDEBUG_H_
 
void udebug_syscall_event(void);
void udebug_stopping_point(void);
void udebug_stoppable_begin(void);
void udebug_stoppable_end(void);
 
#endif
 
/branches/tracing/kernel/generic/src/proc/task.c
175,6 → 175,7
ta->stop_request = false;
ta->debug_begin_call = NULL;
ta->debug_go_call = NULL;
ta->not_stoppable_count = 0;
ipc_answerbox_init(&ta->answerbox, ta);
for (i = 0; i < IPC_MAX_PHONES; i++)
/branches/tracing/kernel/generic/src/proc/thread.c
412,6 → 412,7
spinlock_lock(&task->lock);
atomic_inc(&task->refcount);
atomic_inc(&task->lifecount);
++task->not_stoppable_count;
list_append(&t->th_link, &task->th_head);
spinlock_unlock(&task->lock);
 
/branches/tracing/kernel/generic/src/syscall/syscall.c
98,9 → 98,10
{
unative_t rc;
 
if (id < SYSCALL_END)
if (id < SYSCALL_END) {
udebug_stoppable_begin();
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
else {
} else {
klog_printf("TASK %llu: Unknown syscall id %llx", TASK->taskid,
id);
task_kill(TASK->taskid);
111,7 → 112,7
thread_exit();
 
udebug_syscall_event();
udebug_stopping_point();
udebug_stoppable_end();
return rc;
}
/branches/tracing/kernel/generic/src/ipc/sysipc.c
307,29 → 307,37
 
#include <console/klog.h>
 
static void debug_begin(call_t *call, phone_t *phone)
static int debug_begin(call_t *call, phone_t *phone)
{
task_t *ta;
 
klog_printf("debug_begin()");
 
ta = get_lock_callee_task(phone);
klog_printf("debugging task %llu\n", ta->taskid);
klog_printf("debugging task %llu", ta->taskid);
 
if (ta->being_debugged != false) {
IPC_SET_RETVAL(call->data, EBUSY);
ipc_answer(&ta->answerbox, call);
 
spinlock_unlock(&ta->lock);
return;
klog_printf("debug_begin(): busy error");
return EBUSY;
}
 
ta->being_debugged = true;
ta->stop_request = true;
ta->debug_begin_call = call;
 
if (ta->not_stoppable_count == 0) {
ta->debug_begin_call = NULL;
ta->stop_request = false;
spinlock_unlock(&ta->lock);
klog_printf("debug_begin(): immediate backsend");
return 1; /* actually we need backsend with 0 retval */
}
 
spinlock_unlock(&ta->lock);
 
klog_printf("debug_begin() done");
klog_printf("debug_begin() done (wait for stoppability)");
return 0;
}
 
static void debug_go(call_t *call, phone_t *phone)
341,13 → 349,15
klog_printf("debug_go()");
ta = get_lock_callee_task(phone);
 
ta->debug_go_call = call;
 
l = ta->th_head.next;
if (l != &TASK->th_head) {
t = list_get_instance(l, thread_t, th_link);
klog_printf("debug_go(): waitq_wakeup");
waitq_wakeup(&t->go_wq, WAKEUP_FIRST);
}
 
ta->debug_go_call = call;
spinlock_unlock(&ta->lock);
}
 
402,7 → 412,9
}
break;
case IPC_M_DEBUG_BEGIN:
debug_begin(call, phone);
/* actually need possibility of backsend with 0 result code */
rc = debug_begin(call, phone);
if (rc != 0) return rc;
break;
case IPC_M_DEBUG_GO:
debug_go(call, phone);
/branches/tracing/kernel/generic/src/udebug/udebug.c
12,26 → 12,66
#include <udebug.h>
#include <arch.h>
 
void udebug_stopping_point(void)
void udebug_stoppable_begin(void)
{
if (TASK->stop_request) { /* locking! */
klog_printf("udebug_stopping_point");
IPC_SET_RETVAL(TASK->debug_begin_call->data, 0);
ipc_answer(&TASK->answerbox, TASK->debug_begin_call);
int nsc;
call_t *db_call;
 
spinlock_lock(&TASK->lock);
 
nsc = --TASK->not_stoppable_count;
db_call = TASK->debug_begin_call;
 
if (TASK->stop_request == true) {
klog_printf("udebug_stoppable_begin");
klog_printf(" - nsc := %d", nsc);
}
 
if (TASK->stop_request == true && nsc == 0) {
TASK->stop_request = false;
TASK->debug_begin_call = NULL;
spinlock_unlock(&TASK->lock);
 
IPC_SET_RETVAL(db_call->data, 0);
klog_printf("udebug_stoppable_begin/ipc_answer");
ipc_answer(&TASK->answerbox, db_call);
} else {
spinlock_unlock(&TASK->lock);
}
}
 
void udebug_stoppable_end(void)
{
restart:
spinlock_lock(&TASK->lock);
 
if (TASK->stop_request) {
TASK->debug_begin_call = NULL;
spinlock_unlock(&TASK->lock);
klog_printf("udebug_stoppable_end: waitq_sleep");
waitq_sleep(&THREAD->go_wq);
goto restart;
/* must try again - have to lose stoppability atomically */
} else {
++TASK->not_stoppable_count;
spinlock_unlock(&TASK->lock);
}
}
 
void udebug_syscall_event(void)
{
spinlock_lock(&TASK->lock);
/* being debugged + have go */
if (TASK->being_debugged && !TASK->stop_request) { /* locking! */
klog_printf("udebug_syscall_event");
IPC_SET_RETVAL(TASK->debug_go_call->data, 0);
klog_printf("udebug_syscall_event/ipc_answer");
 
ipc_answer(&TASK->answerbox, TASK->debug_go_call);
spinlock_unlock(&TASK->lock);
waitq_sleep(&THREAD->go_wq);
} else {
spinlock_unlock(&TASK->lock);
}
}