diff --git a/rtemsbsd/src/rtems-bsd-thread.c b/rtemsbsd/src/rtems-bsd-thread.c index f6b9abf1..230fa8fa 100644 --- a/rtemsbsd/src/rtems-bsd-thread.c +++ b/rtemsbsd/src/rtems-bsd-thread.c @@ -45,13 +45,102 @@ #include #include #include +#include +#include +#include RTEMS_CHAIN_DEFINE_EMPTY(rtems_bsd_thread_chain); /* FIXME: What to do with the credentials? */ static struct ucred FIXME_ucred = { - .cr_ref = 1 + .cr_ref = 1 /* reference count */ }; +static struct proc FIXME_proc = { + .p_ucred = NULL /* (c) Process owner's identity. */ +}; +static int prison_init = 1; +static struct prison FIXME_prison = { + .pr_parent = NULL +}; + +static struct thread * +rtems_bsd_thread_init_note( rtems_id id ) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + unsigned index = 0; + char name [5] = "_???"; + struct thread *td = malloc(sizeof(struct thread), M_TEMP, M_WAITOK | M_ZERO); + struct proc *proc; + + if ( td == NULL ) + return td; + + sc = rtems_task_set_note( id, RTEMS_NOTEPAD_0, ( uint32_t )td ); + if (sc != RTEMS_SUCCESSFUL) { + free(td, M_TEMP); + return NULL; + } + + index = rtems_object_id_get_index(id); + snprintf(name + 1, sizeof(name) - 1, "%03u", index); + sc = rtems_object_set_name(id, name); + if (sc != RTEMS_SUCCESSFUL) { + rtems_task_delete(id); + free(td, M_TEMP); + return NULL; + } + + td->td_id = id; + td->td_ucred = crhold(&FIXME_ucred); + + td->td_proc = &FIXME_proc; + if (td->td_proc->p_ucred != NULL) + return td; + + if (prison_init ) { + mtx_init(&FIXME_prison.pr_mtx, "prison lock", NULL, MTX_DEF | MTX_DUPOK); + prison_init = 0; + } + + FIXME_ucred.cr_prison = &FIXME_prison; /* jail(2) */ + + td->td_proc->p_ucred = crhold(&FIXME_ucred); + mtx_init(&td->td_proc->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); + td->td_proc->p_pid = getpid(); + td->td_proc->p_fibnum = 0; + + return td; +} + +/* + * XXX Threads which delete themselves will leak this + * XXX Maybe better integrated into the TCB OR a task variable. + * XXX but this is OK for now + */ +struct thread *rtems_get_curthread(void) +{ + struct thread *td; + rtems_status_code sc; + rtems_id id; + + /* + * If we already have a struct thread associated with this thread, + * obtain it + */ + id = rtems_task_self(); + + sc = rtems_task_get_note( id, RTEMS_NOTEPAD_0, (uint32_t *) &td ); + if (sc != RTEMS_SUCCESSFUL) { + panic("rtems_get_curthread: get note Error\n"); + } + + td = rtems_bsd_thread_init_note( id); + if ( td == NULL ){ + panic("rtems_get_curthread: Unable to generate thread note\n"); + } + + return td; +} static int rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg, int flags, int pages, const char *fmt, va_list ap) @@ -80,23 +169,10 @@ rtems_bsd_thread_start(struct thread **td_ptr, void (*func)(void *), void *arg, return ENOMEM; } - sc = rtems_task_set_note( id, RTEMS_NOTEPAD_0, ( uint32_t )td ); - if (sc != RTEMS_SUCCESSFUL) { - free(td, M_TEMP); - - return ENOMEM; - } - - index = rtems_object_id_get_index(id); - snprintf(name + 1, sizeof(name) - 1, "%03u", index); - sc = rtems_object_set_name(id, name); - if (sc != RTEMS_SUCCESSFUL) { - rtems_task_delete(id); - free(td, M_TEMP); - + td = rtems_bsd_thread_init_note( id ); + if (!td) return ENOMEM; - } - + sc = rtems_task_start(id, (rtems_task_entry) func, (rtems_task_argument) arg); if (sc != RTEMS_SUCCESSFUL) { rtems_task_delete(id);