#include "synchro.h" #include "alloc.h" #include "assert.h" #include "irq.h" #include "klibc.h" #include "list.h" #include "time.h" int mutexInit(struct mutex *m) { m->owner = NULL; m->wait = (struct wait_queue *)malloc(sizeof(struct wait_queue)); if (!m->wait) return ENOMEM; waitQueueInit(m->wait); 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%p. owned by 0x%p 0x%p\n", m, m->owner, getCurrentThread()); } #endif waitQueueFree(m->wait); free(m->wait); } else { ret = EBUSY; } restore_IRQs(flags); } return ret; } int mutexLock(struct mutex *m) { uint32_t flags; struct thread *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; waitUp(m->wait); restore_IRQs(flags); return 0; } int semInit(struct semaphore *sem, int initVal) { sem->count = initVal; waitQueueInit(&sem->wait); return 0; } int semFree(struct semaphore *sem) { return waitQueueFree(&sem->wait); } int semDown(struct semaphore *sem, unsigned long timeout) { uint32_t flags; int ret = 0; disable_IRQs(flags); sem->count--; if (sem->count < 0) { ret = waitTimeout(&sem->wait, timeout); if (ret) { sem->count++; } } restore_IRQs(flags); return ret; } int semTryDown(struct semaphore *sem) { uint32_t flags; int ret = -EBUSY; disable_IRQs(flags); if (sem->count > 1) { ret = 0; sem->count--; } restore_IRQs(flags); return ret; } int semUp(struct semaphore *sem) { uint32_t flags; int ret = 0; disable_IRQs(flags); sem->count++; ret = waitUpNb(&sem->wait, 1); restore_IRQs(flags); return ret; }