diff options
author | Christian Cunningham <cc@localhost> | 2022-03-18 13:54:07 -0700 |
---|---|---|
committer | Christian Cunningham <cc@localhost> | 2022-03-18 13:54:07 -0700 |
commit | 784ca276c9e701629652a8d3ee194d41ecc06fdf (patch) | |
tree | 06089aaeb6b0bb328ddaee51344236ec98f1ae45 /src/util | |
parent | 70ad8784f73722872d18795badd202562ada000f (diff) |
Deadlock prevention for managed mutexs
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/mutex.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/util/mutex.c b/src/util/mutex.c index 226bfbc..802558e 100644 --- a/src/util/mutex.c +++ b/src/util/mutex.c @@ -1,4 +1,6 @@ +#include <cpu.h> #include <util/mutex.h> +#include <util/lock.h> #include <globals.h> void mutex_init(void) @@ -50,3 +52,37 @@ unsigned char delete_mutex(struct Mutex* m) prepend_to_queue(entry, &mutex_manager.free); return 0; } + +void lock_mutex(struct Mutex* m) +{ + struct Thread* rthread = scheduler.rthread; + unsigned long rpid = rthread->pid; + unsigned long mode = getmode() & 0x1F; + if (mode == 0x10) { + sys1(SYS_LOCK, m); + // Find this mutex + struct Entry* mentry = find_value(m, &mutex_manager.used); + // If it is not a managed mutex, break away + if (mentry == 0) + return; + // Get the next entry + mentry = mentry->next->next; + // Ensure this thread locks all mutexs sequentially + // To avoid a deadlock + while (mentry->entry_type == VALUE_ENTRY) { + struct Mutex* vmutex = mentry->value; + // If this thread had locked it + // Toggle the lock to prevent deadlock + if (vmutex->pid == rpid) { + sys1(SYS_UNLOCK, m); + sys1(SYS_LOCK, m); + } + mentry = mentry->next; + } + } +} + +void unlock_mutex(struct Mutex* m) +{ + unlock((struct Lock*)m); +} |