From cd53dfd7f32dcc0275c47fb024abb07ad43300f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Thu, 28 Apr 2022 19:40:18 +0200 Subject: [PATCH] Fix thread stack allocation We need to allocate the stack before the thread starts running. --- include/aos/threads.h | 4 ++-- lib/aos/threads.c | 32 ++++++++++++++++++++++---------- usr/init/main.c | 5 ++--- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/aos/threads.h b/include/aos/threads.h index 4e6d2c9..bad1142 100644 --- a/include/aos/threads.h +++ b/include/aos/threads.h @@ -35,6 +35,8 @@ typedef int (*thread_func_t)(void *); struct thread *thread_create(thread_func_t start_func, void *data); struct thread *thread_create_varstack(thread_func_t start_func, void *arg, size_t stacksize); +struct thread *thread_create_varstack_alloc(thread_func_t start_func, void *arg, + size_t stacksize); void thread_yield(void); void thread_yield_dispatcher(struct capref endpoint); void thread_exit(int status); @@ -122,8 +124,6 @@ static inline void thread_once(thread_once_t *control, void (*func)(void)) { */ void thread_set_status(int status); -void thread_allocate_stack(struct thread *thread); - __END_DECLS #endif // LIBBARRELFISH_THREADS_H diff --git a/lib/aos/threads.c b/lib/aos/threads.c index 7845b4b..df6ada1 100644 --- a/lib/aos/threads.c +++ b/lib/aos/threads.c @@ -463,6 +463,28 @@ struct thread *thread_create(thread_func_t start_func, void *arg) return thread_create_varstack(start_func, arg, THREADS_DEFAULT_STACK_BYTES); } +/** + * \brief Like thread_create_varstack, but allocate all pages of + * the thread stack before starting the thread. + */ +struct thread *thread_create_varstack_alloc(thread_func_t start_func, void *arg, + size_t stacksize) +{ + struct thread *newthread = thread_create_unrunnable(start_func, arg, stacksize); + if (newthread) { + for (volatile uint8_t *p = newthread->stack; (void*)p < newthread->stack_top; p += BASE_PAGE_SIZE) { + *p; // cause a page fault + } + // enqueue on runq + dispatcher_handle_t handle = disp_disable(); + struct dispatcher_generic *disp_gen = get_dispatcher_generic(handle); + newthread->disp = handle; + thread_enqueue(newthread, &disp_gen->runq); + disp_enable(handle); + } + return newthread; +} + /** * \brief Wait for termination of another thread * @@ -1462,13 +1484,3 @@ void thread_deliver_exception_disabled(dispatcher_handle_t handle, disp_resume(handle, &thread->regs); } - -/** - * \brief Allocate all pages of the thread stack. - */ -void thread_allocate_stack(struct thread *thread) -{ - for (volatile uint8_t *p = thread->stack; (void*)p < thread->stack_top; p += BASE_PAGE_SIZE) { - *p; // cause a page fault - } -} diff --git a/usr/init/main.c b/usr/init/main.c index 553772a..fa7a968 100644 --- a/usr/init/main.c +++ b/usr/init/main.c @@ -247,11 +247,10 @@ app_main(int argc, char *argv[]) { ram_alloc_set(ram_alloc_remote_core); - struct thread *urpc_server_thread = thread_create(urpc_server, &urpc_to_app_server); // Allocate all pages of the thread stack now. - // We can't have page fault while the thread is running, + // We can't have page faults while the thread is running, // because URPC calls may only be done from the main thread. - thread_allocate_stack(urpc_server_thread); + thread_create_varstack_alloc(urpc_server, &urpc_to_app_server, THREADS_DEFAULT_STACK_BYTES); // TODO: Spawn system processes etc. here