Files
mop3/kernel/proc/mutex.c

65 lines
1.4 KiB
C

#include <libk/assert.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <proc/mutex.h>
#include <proc/proc.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
void proc_mutex_lock (struct proc* proc, struct proc_mutex* mutex) {
spin_lock_ctx_t ctxmt;
try:
spin_lock (&mutex->resource->lock, &ctxmt);
if (!mutex->locked || mutex->owner == proc) {
mutex->locked = true;
mutex->owner = proc;
spin_unlock (&mutex->resource->lock, &ctxmt);
return;
}
spin_unlock (&mutex->resource->lock, &ctxmt);
proc_suspend (proc, &mutex->suspension_q);
goto try;
}
bool proc_mutex_unlock (struct proc* proc, struct proc_mutex* mutex) {
spin_lock_ctx_t ctxmt, ctxsq;
spin_lock (&mutex->resource->lock, &ctxmt);
if (mutex->owner != proc) {
spin_unlock (&mutex->resource->lock, &ctxmt);
return false;
}
spin_lock (&mutex->suspension_q.lock, &ctxsq);
struct proc* resumed_proc;
struct rb_node_link* node;
rbtree_first (&mutex->suspension_q.proc_tree, node);
if (node) {
resumed_proc = rbtree_entry (node, struct proc, suspension_link);
mutex->owner = resumed_proc;
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
spin_unlock (&mutex->resource->lock, &ctxmt);
proc_resume (resumed_proc);
return true;
}
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
mutex->locked = false;
mutex->owner = NULL;
spin_unlock (&mutex->resource->lock, &ctxmt);
return true;
}