From 765c1023d6dd37520a2c132bf09f23fa1cc3a1b1 Mon Sep 17 00:00:00 2001 From: Philippe Aubertin Date: Tue, 19 Nov 2024 02:26:44 -0500 Subject: [PATCH 1/2] thread_await() --- include/kernel/domain/entities/thread.h | 4 +- kernel/application/syscalls/await_thread.c | 23 +-------- kernel/domain/entities/thread.c | 60 ++++++++++++++++------ 3 files changed, 47 insertions(+), 40 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..babefdd8 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 * @@ -387,31 +415,29 @@ void thread_block_current_and_unlock(spinlock_t *lock) { machine_switch_thread_and_unlock(current, to, lock); } -/** - * 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); +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; } /** From 3278ad34f1afea6294bce78200b0f1fa8d19c488 Mon Sep 17 00:00:00 2001 From: Philippe Aubertin Date: Tue, 19 Nov 2024 02:29:36 -0500 Subject: [PATCH 2/2] Function header --- kernel/domain/entities/thread.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/domain/entities/thread.c b/kernel/domain/entities/thread.c index babefdd8..454c8397 100644 --- a/kernel/domain/entities/thread.c +++ b/kernel/domain/entities/thread.c @@ -415,6 +415,13 @@ void thread_block_current_and_unlock(spinlock_t *lock) { machine_switch_thread_and_unlock(current, to, lock); } +/** + * Block until thread terminates + * + * @param thread awaited thread + * @return zero on success, negated error code on failure + * + */ int thread_await(thread_t *thread) { thread_t *current = get_current_thread();