diff options
author | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
---|---|---|
committer | nthnluu <nate1299@me.com> | 2024-01-28 21:20:27 -0500 |
commit | c63f340d90800895f007de64b7d2d14624263331 (patch) | |
tree | 2c0849fa597dd6da831c8707b6f2603403778d7b /kernel/proc/kmutex.c |
Created student weenix repository
Diffstat (limited to 'kernel/proc/kmutex.c')
-rw-r--r-- | kernel/proc/kmutex.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/kernel/proc/kmutex.c b/kernel/proc/kmutex.c new file mode 100644 index 0000000..0433468 --- /dev/null +++ b/kernel/proc/kmutex.c @@ -0,0 +1,88 @@ +// SMP.1 + SMP.3 +// spinlock + mask interrupts +#include "proc/kmutex.h" +#include "globals.h" +#include "main/interrupt.h" +#include <errno.h> + +/* + * IMPORTANT: Mutexes can _NEVER_ be locked or unlocked from an + * interrupt context. Mutexes are _ONLY_ lock or unlocked from a + * thread context. + */ + +/* + * Checks for the specific deadlock case where: + * curthr wants mtx, but the owner of mtx is waiting on a mutex that curthr is + * holding + */ +#define DEBUG_DEADLOCKS 1 +void detect_deadlocks(kmutex_t *mtx) +{ +#if DEBUG_DEADLOCKS + list_iterate(&curthr->kt_mutexes, held, kmutex_t, km_link) + { + list_iterate(&held->km_waitq.tq_list, waiter, kthread_t, kt_qlink) + { + if (waiter == mtx->km_holder) + { + panic( + "detected deadlock between P%d and P%d (mutexes 0x%p, " + "0x%p)\n", + curproc->p_pid, waiter->kt_proc->p_pid, held, mtx); + } + } + } +#endif +} + +/* + * Initializes the members of mtx + */ +void kmutex_init(kmutex_t *mtx) +{ + NOT_YET_IMPLEMENTED("PROCS: ***none***"); +} + +/* + * Obtains a mutex, potentially blocking. + * + * Hints: + * You are strongly advised to maintain the kt_mutexes member of curthr and call + * detect_deadlocks() to help debugging. + */ +void kmutex_lock(kmutex_t *mtx) +{ + NOT_YET_IMPLEMENTED("PROCS: ***none***"); +} + +/* + * Releases a mutex. + * + * Hints: + * Again, you are strongly advised to maintain kt_mutexes. + * Use sched_wakeup_on() to hand off the mutex - think carefully about how + * these two functions interact to ensure that the mutex's km_holder is + * properly set before the new owner is runnable. + */ +void kmutex_unlock(kmutex_t *mtx) +{ + NOT_YET_IMPLEMENTED("PROCS: ***none***"); +} + +/* + * Checks if mtx's wait queue is empty. + */ +long kmutex_has_waiters(kmutex_t *mtx) +{ + return !sched_queue_empty(&mtx->km_waitq); + ; +} + +/* + * Checks if the current thread owns mtx. + */ +inline long kmutex_owns_mutex(kmutex_t *mtx) +{ + return curthr && mtx->km_holder == curthr; +} |