diff --git a/src/kernel/include/mutex.h b/src/kernel/include/mutex.h index 777d909..88b88b2 100644 --- a/src/kernel/include/mutex.h +++ b/src/kernel/include/mutex.h @@ -1,4 +1,17 @@ #ifndef MUTEX_H #define MUTEX_H +#include "task.h" +#include + +typedef struct { + Task *owner; + Task *waiting; + bool is_locked; +} Mutex; + +void mutex_init(Mutex *mutex); +void mutex_lock(Mutex *mutex); +void mutex_unlock(Mutex *mutex); + #endif \ No newline at end of file diff --git a/src/kernel/src/mutex.c b/src/kernel/src/mutex.c index e69de29..e9f8481 100644 --- a/src/kernel/src/mutex.c +++ b/src/kernel/src/mutex.c @@ -0,0 +1,36 @@ +#include "mutex.h" +#include "scheduler.h" +#include "port.h" +#include "fault_indicator.h" +#include + +void mutex_init(Mutex *mutex) { + mutex->is_locked = false; + mutex->owner = NULL; + mutex->waiting = NULL; +} + +void mutex_lock(Mutex *mutex) { + while (mutex->is_locked) { + if (mutex->waiting != NULL) { + warning_light_scheduler(); + } + mutex->waiting = current_task; + current_task->state = BLOCKED; + port_trigger_context_switch(); + } + + mutex->is_locked = true; + mutex->owner = current_task; +} + +void mutex_unlock(Mutex *mutex) { + mutex->is_locked = false; + mutex->owner = NULL; + + if (mutex->waiting != NULL) { + mutex->waiting->state = READY; + mutex->waiting = NULL; + port_trigger_context_switch(); + } +} \ No newline at end of file