From f6a78b3516193a7f987df940e88e29ef2473ca98 Mon Sep 17 00:00:00 2001 From: Martin Eyben Date: Tue, 25 Mar 2025 10:35:02 +0100 Subject: [PATCH] feat: add deadlock verification --- src/thread/thread.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/thread/thread.c b/src/thread/thread.c index 70a8425..cc825ac 100644 --- a/src/thread/thread.c +++ b/src/thread/thread.c @@ -9,6 +9,7 @@ #include #include #include +#include #define FINISHED 0x1 #define IS_FINISHED(entry) (entry->status & FINISHED) @@ -49,7 +50,7 @@ static struct context_entry* running = NULL; int thread_yield(void) { - TRACE("thread_yield"); + //TRACE("thread_yield"); if (TAILQ_EMPTY(&head)) { return 0; } @@ -140,10 +141,20 @@ int thread_join(thread_t thread, void** retval) TRACE("Join thread %p", thread); struct context_entry* entry = thread; // Check if the target is not already waited by another - if (IS_WAITED(entry) || IS_WAITING(entry) && GET_WAITED_THREAD(entry) == running) { + if (IS_WAITED(entry)) { return -1; } + // Check if there is a deadlock + struct context_entry* parent = thread; + while (IS_WAITING(parent)) { + if (GET_WAITED_THREAD(parent) == running) { + TRACE("Deadlock detected"); + return EDEADLK; + } + parent = GET_WAITED_THREAD(parent); + } + if (!IS_FINISHED(entry)) { // Use status to be in waiting state running->status |= WAITING; @@ -152,6 +163,8 @@ int thread_join(thread_t thread, void** retval) entry->status |= WAITED; // Use retvalue to share which thread is currently waiting for this thread entry->retvalue = running; + + DBG("%p is waiting for %p", running, entry); do { thread_yield(); } while (!IS_FINISHED(entry));