From c5d8f934e3433024b5e3d5a0aa6e2fb8ec6fbf65 Mon Sep 17 00:00:00 2001 From: Po-Yi Tsai Date: Sat, 1 Jul 2023 01:02:19 +0800 Subject: [PATCH] Lab 5 C: Fix run queue corruption `deliver_signal` depends on the invariant that, if the `is_waiting` status bit is set on a thread, then that thread must be in a wait queue. However, when waking up a thread from a wait queue, the `is_waiting` status bit was not correctly cleared, causing `deliver_signal` to corrupt the run queue. --- lab5/c/include/oscos/sched.h | 4 ++-- lab5/c/src/sched/sched.c | 3 ++- lab5/c/src/xcpt/syscall/uart-read.c | 4 ++-- lab5/c/src/xcpt/syscall/uart-write.c | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lab5/c/include/oscos/sched.h b/lab5/c/include/oscos/sched.h index bd48e328c..2e92b5284 100644 --- a/lab5/c/include/oscos/sched.h +++ b/lab5/c/include/oscos/sched.h @@ -140,8 +140,8 @@ void schedule(void); /// scheduler. void suspend_to_wait_queue(thread_list_node_t *wait_queue); -/// \brief Adds every thread in the given wait queue to the run queue. -void add_all_threads_to_run_queue(thread_list_node_t *wait_queue); +/// \brief Wake up every thread in the given wait queue. +void wake_up_all_threads_in_wait_queue(thread_list_node_t *wait_queue); /// \brief Gets a process by its PID. process_t *get_process_by_id(size_t pid); diff --git a/lab5/c/src/sched/sched.c b/lab5/c/src/sched/sched.c index ebcf79e27..3f937739e 100644 --- a/lab5/c/src/sched/sched.c +++ b/lab5/c/src/sched/sched.c @@ -542,9 +542,10 @@ void suspend_to_wait_queue(thread_list_node_t *const wait_queue) { _suspend_to_wait_queue(wait_queue); } -void add_all_threads_to_run_queue(thread_list_node_t *const wait_queue) { +void wake_up_all_threads_in_wait_queue(thread_list_node_t *const wait_queue) { thread_t *thread; while ((thread = _remove_first_thread_from_queue(wait_queue))) { + thread->status.is_waiting = false; _add_thread_to_run_queue(thread); } } diff --git a/lab5/c/src/xcpt/syscall/uart-read.c b/lab5/c/src/xcpt/syscall/uart-read.c index e4646bc77..12e00d39c 100644 --- a/lab5/c/src/xcpt/syscall/uart-read.c +++ b/lab5/c/src/xcpt/syscall/uart-read.c @@ -28,8 +28,8 @@ ssize_t sys_uart_read(char buf[const], const size_t size) { thread_t *const curr_thread = current_thread(); - console_notify_read_ready((void (*)(void *))add_all_threads_to_run_queue, - &_wait_queue); + console_notify_read_ready( + (void (*)(void *))wake_up_all_threads_in_wait_queue, &_wait_queue); suspend_to_wait_queue(&_wait_queue); XCPT_MASK_ALL(); diff --git a/lab5/c/src/xcpt/syscall/uart-write.c b/lab5/c/src/xcpt/syscall/uart-write.c index aa23d2722..d612ea85e 100644 --- a/lab5/c/src/xcpt/syscall/uart-write.c +++ b/lab5/c/src/xcpt/syscall/uart-write.c @@ -27,8 +27,8 @@ size_t sys_uart_write(const char buf[const], const size_t size) { thread_t *const curr_thread = current_thread(); - console_notify_write_ready((void (*)(void *))add_all_threads_to_run_queue, - &_wait_queue); + console_notify_write_ready( + (void (*)(void *))wake_up_all_threads_in_wait_queue, &_wait_queue); suspend_to_wait_queue(&_wait_queue); XCPT_MASK_ALL();