From 478b0e8b1cf06b5aa24e253e4b3ca9c3160f661b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 8 Mar 2012 16:12:01 -0800 Subject: [PATCH] libthreads: cleanup main thread initialization Create a "thread" for the primary context, rather than handling special logic for a separate "cleanup" ucontext_t. --- libthreads.c | 68 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/libthreads.c b/libthreads.c index 5ede8d7..6da8fbf 100644 --- a/libthreads.c +++ b/libthreads.c @@ -9,16 +9,45 @@ #define STACK_SIZE (1024 * 1024) static struct thread *current; -static ucontext_t *cleanup; static void *stack_allocate(size_t size) { return malloc(size); } +static int create_context(struct thread *t) +{ + int ret; + + memset(&t->context, 0, sizeof(t->context)); + ret = getcontext(&t->context); + if (ret) + return ret; + + /* t->start_routine == NULL means this is our initial context */ + if (!t->start_routine) + return 0; + + /* Initialize new managed context */ + t->stack = stack_allocate(STACK_SIZE); + t->context.uc_stack.ss_sp = t->stack; + t->context.uc_stack.ss_size = STACK_SIZE; + t->context.uc_stack.ss_flags = 0; + t->context.uc_link = ¤t->context; + makecontext(&t->context, t->start_routine, 1, t->arg); + + return 0; +} + +static int create_initial_thread(struct thread *t) +{ + memset(t, 0, sizeof(*t)); + return create_context(t); +} + int thread_create(struct thread *t, void (*start_routine), void *arg) { - static int created; + static int created = 1; ucontext_t local; DBG(); @@ -30,32 +59,17 @@ int thread_create(struct thread *t, void (*start_routine), void *arg) t->arg = arg; /* Initialize state */ - getcontext(&t->context); - t->stack = stack_allocate(STACK_SIZE); - t->context.uc_stack.ss_sp = t->stack; - t->context.uc_stack.ss_size = STACK_SIZE; - t->context.uc_stack.ss_flags = 0; - if (current) - t->context.uc_link = ¤t->context; - else - t->context.uc_link = cleanup; - makecontext(&t->context, t->start_routine, 1, t->arg); - - return 0; + return create_context(t); } void thread_start(struct thread *t) { + struct thread *old = current; DBG(); - if (current) { - struct thread *old = current; - current = t; - swapcontext(&old->context, ¤t->context); - } else { - current = t; - swapcontext(cleanup, ¤t->context); - } + current = t; + swapcontext(&old->context, ¤t->context); + DBG(); } @@ -83,14 +97,14 @@ void user_main() int main() { - struct thread t; - ucontext_t main_context; + struct thread main_thread, user_thread; - cleanup = &main_context; + create_initial_thread(&main_thread); + current = &main_thread; - thread_create(&t, &user_main, NULL); + thread_create(&user_thread, &user_main, NULL); - thread_start(&t); + thread_start(&user_thread); DBG(); -- 2.34.1