From 87a6c65aba4005a238887b0116ca9f68bdec78d9 Mon Sep 17 00:00:00 2001 From: Philippe Aubertin <39178965+phaubertin@users.noreply.github.com> Date: Tue, 19 Nov 2024 02:30:47 -0500 Subject: [PATCH] Refactoring: thread_await() (#87) Refactor ` thread_await()` into a separate function. --- include/kernel/domain/entities/thread.h | 4 +- kernel/application/syscalls/await_thread.c | 23 +------- kernel/domain/entities/thread.c | 61 +++++++++++++++++----- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/include/kernel/domain/entities/thread.h b/include/kernel/domain/entities/thread.h index 67c4a6d8..c7c18b60 100644 --- a/include/kernel/domain/entities/thread.h +++ b/include/kernel/domain/entities/thread.h @@ -50,6 +50,8 @@ void thread_run_first(thread_t *thread); void thread_run(thread_t *thread); +void thread_yield_current(void); + void thread_terminate_current(void); void thread_switch_to(thread_t *to); @@ -58,7 +60,7 @@ void thread_switch_to_and_block(thread_t *to); void thread_block_current_and_unlock(spinlock_t *lock); -void thread_yield_current(void); +int thread_await(thread_t *thread); void thread_set_local_storage(thread_t *thread, addr_t addr, size_t size); diff --git a/kernel/application/syscalls/await_thread.c b/kernel/application/syscalls/await_thread.c index d698172f..7fbb66a4 100644 --- a/kernel/application/syscalls/await_thread.c +++ b/kernel/application/syscalls/await_thread.c @@ -49,28 +49,7 @@ static int with_thread(descriptor_t *thread_desc) { return -JINUE_EPERM; } - thread_t *current = get_current_thread(); - - if(thread == current) { - return -JINUE_EDEADLK; - } - - spin_lock(&thread->await_lock); - - if(thread->state == THREAD_STATE_CREATED || thread->awaiter != NULL) { - spin_unlock(&thread->await_lock); - return -JINUE_ESRCH; - } - - thread->awaiter = current; - - if(thread->state == THREAD_STATE_ZOMBIE) { - spin_unlock(&thread->await_lock); - } else { - thread_block_current_and_unlock(&thread->await_lock); - } - - return 0; + return thread_await(thread); } int await_thread(int fd) { diff --git a/kernel/domain/entities/thread.c b/kernel/domain/entities/thread.c index ef35ed28..454c8397 100644 --- a/kernel/domain/entities/thread.c +++ b/kernel/domain/entities/thread.c @@ -29,6 +29,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include #include @@ -270,6 +271,33 @@ static thread_t *reschedule(bool current_can_run) { return to; } +/** + * Yield the current thread + * + * The current thread is added at the tail of the ready queue. It continues + * running if no other thread is ready to run. + */ +void thread_yield_current(void) { + thread_t *current = get_current_thread(); + thread_t *to = reschedule(true); + + if(to == current) { + return; + } + + to->state = THREAD_STATE_RUNNING; + + if(current->process != to->process) { + process_switch_to(to->process); + } + + spin_lock(&ready_queue.lock); + + thread_ready_locked(current); + + machine_switch_thread_and_unlock(current, to, &ready_queue.lock); +} + /** * Terminate the current thread * @@ -388,30 +416,35 @@ void thread_block_current_and_unlock(spinlock_t *lock) { } /** - * Yield the current thread + * Block until thread terminates * - * The current thread is added at the tail of the ready queue. It continues - * running if no other thread is ready to run. + * @param thread awaited thread + * @return zero on success, negated error code on failure + * */ -void thread_yield_current(void) { - thread_t *current = get_current_thread(); - thread_t *to = reschedule(true); +int thread_await(thread_t *thread) { + thread_t *current = get_current_thread(); - if(to == current) { - return; + if(thread == current) { + return -JINUE_EDEADLK; } - to->state = THREAD_STATE_RUNNING; + spin_lock(&thread->await_lock); - if(current->process != to->process) { - process_switch_to(to->process); + if(thread->state == THREAD_STATE_CREATED || thread->awaiter != NULL) { + spin_unlock(&thread->await_lock); + return -JINUE_ESRCH; } - spin_lock(&ready_queue.lock); + thread->awaiter = current; - thread_ready_locked(current); + if(thread->state == THREAD_STATE_ZOMBIE) { + spin_unlock(&thread->await_lock); + } else { + thread_block_current_and_unlock(&thread->await_lock); + } - machine_switch_thread_and_unlock(current, to, &ready_queue.lock); + return 0; } /**