aboutsummaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-03-18 13:54:07 -0700
committerChristian Cunningham <cc@localhost>2022-03-18 13:54:07 -0700
commit784ca276c9e701629652a8d3ee194d41ecc06fdf (patch)
tree06089aaeb6b0bb328ddaee51344236ec98f1ae45 /src/util
parent70ad8784f73722872d18795badd202562ada000f (diff)
Deadlock prevention for managed mutexs
Diffstat (limited to 'src/util')
-rw-r--r--src/util/mutex.c36
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);
+}