#include <ubixos/spinlock.h> #include <ubixos/kmalloc.h> #include <ubixos/schedule.h> #include <types.h> spinlock_t * spinlockCreate() { spinlock_t * lock = kmalloc(sizeof(spinlock_t)); if (lock == NULL) kpanic("SPINLOCK: Couldn't create spinlock\n"); memset(lock, '\0', sizeof(spinlock_t)); return lock; } void spinlockInit(spinlock_t * lock) { memset(lock, '\0', sizeof(spinlock_t)); } void spinlockDelete(spinlock_t * lock) { int i; int notComplete = 1; lock->deleteInProgress = 1; while (notComplete == 1) { notComplete = 0; for (i = 0; i < 16; i++) { while(lock->choiceInProgress[i] != 0) notComplete = 1; while(lock->ticket[i] != 0) notComplete = 1; } } kfree(lock); } int spinlockLock(spinlock_t * lock, int cpuID) { int max_ticket = 0; int i; if (lock->deleteInProgress == 1) return SPINLOCK_FAIL_DELETING; if (lock->owner == cpuID) { lock->count++; return SPINLOCK_SUCCESS; } lock->choiceInProgress[cpuID] = 1; for (i = 0; i < 16; i++) if (lock->ticket[i] >= max_ticket) max_ticket = lock->ticket[i]; max_ticket++; lock->ticket[cpuID] = max_ticket; lock->choiceInProgress[cpuID] = 0; for (i = 0; i < 16; i++) { while(lock->choiceInProgress[i] == 1) ; while (((lock->ticket[i] < max_ticket) || ((lock->ticket[i] == max_ticket) && (i < cpuID))) && (lock->ticket[i] != 0)) ; } lock->owner = cpuID; return SPINLOCK_SUCCESS; } int spinlockUnlock(spinlock_t * lock, int cpuID) { if (lock->owner == cpuID) { lock->count--; if (lock->count != 0) { return SPINLOCK_SUCCESS; } } lock->ticket[cpuID] = 0; lock->owner = -1; return SPINLOCK_SUCCESS; }