Files
mop3/kernel/proc/mutex.c
kamkow1 fea0999726
All checks were successful
Build documentation / build-and-deploy (push) Successful in 33s
Fix scheduler starvation, use lists for scheduling
2026-01-22 11:54:52 +01:00

79 lines
1.8 KiB
C

#include <libk/assert.h>
#include <libk/rbtree.h>
#include <libk/std.h>
#include <libk/string.h>
#include <proc/mutex.h>
#include <proc/proc.h>
#include <sync/spin_lock.h>
#include <sys/debug.h>
bool proc_create_resource_mutex (struct proc_mutex* mutex) {
memset (mutex, 0, sizeof (*mutex));
return true;
}
void proc_cleanup_resource_mutex (struct proc* proc, struct proc_resource* resource) {
struct proc_mutex* mutex = &resource->u.mutex;
proc_mutex_unlock (proc, mutex);
}
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);
DEBUG ("proc->pid=%d\n", proc->pid);
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 = NULL;
struct list_node_link* node = mutex->suspension_q.proc_list;
if (node) {
resumed_proc = list_entry (node, struct proc, suspension_link);
mutex->owner = resumed_proc;
mutex->locked = true;
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
spin_unlock (&mutex->resource->lock, &ctxmt);
proc_resume (resumed_proc);
return true;
}
mutex->locked = false;
mutex->owner = NULL;
spin_unlock (&mutex->suspension_q.lock, &ctxsq);
spin_unlock (&mutex->resource->lock, &ctxmt);
return true;
}