#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;
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))
;
}
return SPINLOCK_SUCCESS;
}
int spinlockUnlock(spinlock_t * lock, int cpuID)
{
lock->ticket[cpuID] = 0;
return SPINLOCK_SUCCESS;
}