#include "synchro.h" #include "alloc.h" #include "assert.h" #include "irq.h" #include "klibc.h" #include "list.h" #include "time.h" struct wait_queue *waitQueues = NULL; int mutexInit(struct mutex *m) { uint32_t flags; m->owner = NULL; m->wait = (struct wait_queue *)malloc(sizeof(struct wait_queue)); if (!m->wait) return ENOMEM; list_init(m->wait->thread); disable_IRQs(flags); list_add_tail(waitQueues, m->wait); restore_IRQs(flags); return 0; } int mutexFree(struct mutex *m) { int ret = 0; if (m) { uint32_t flags; disable_IRQs(flags); if (list_is_empty(m->wait)) { #ifdef DEBUG if (m->owner) { printf("Warning: freeing a owned mutex 0x%. owned by 0x%p 0x%p\n", m, m->owner, getCurrentThread()); } #endif list_delete(waitQueues, m->wait); free(m->wait); } else { ret = EBUSY; } restore_IRQs(flags); } return ret; } int mutexLock(struct mutex *m) { uint32_t flags; struct kthread *current; disable_IRQs(flags); current = getCurrentThread(); assert(m->owner != current); wait_event(m->wait, m->owner == NULL); m->owner = current; restore_IRQs(flags); return 0; } int mutexUnlock(struct mutex *m) { uint32_t flags; disable_IRQs(flags); assert(m->owner == getCurrentThread()); m->owner = NULL; wake_up(m->wait); restore_IRQs(flags); return 0; }