#include <ubixos/spinlock.h>
#include <ubixos/sched.h>

spinLock_t *BigLock = NULL;
spinLock_t *BigLocksLock = NULL;

#define READ 1
#define WRITE 0

void spinWriteLock(spinLock_t *lock, uInt32 id, uInt8 emergency)
{
	spinLock_t *tmp;
	spinLock(&BigLocksLock);
	lock->Type = READ;
	if(emergency)
	{
		tmp = BigLock->First->Next;
		BigLock->First = lock;
		tmp->Previous = lock;
	}
	else
	{
		tmp = BigLock->Last;
		lock->Previous = tmp;
		BigLock->Last = lock;
		lock->Next = NULL;
	}
	spinUnlock(&BigLocksLock);
        while(1)
        {
		spinLock(&BigLocksLock);
                if(BigLock->First->ID != id && BigLock->First->Locked)          
                        break;
		spinUnlock(&BigLocksLock);

        }
}

void spinReadLock(spinLock_t *lock, uInt32 id, uInt8 emergency)
{
        spinLock_t *tmp;
        spinLock(&BigLocksLock);
	lock->Type = READ;
        if(emergency)
        {
                tmp = BigLock->First->Next;
                BigLock->First = lock;
                tmp->Previous = lock;
        }
        else
        {
                tmp = BigLock->Last;
                lock->Previous = tmp;
                BigLock->Last = lock;
                lock->Next = NULL;
        }
	spinUnlock(&BigLocksLock);
	while(1)
	{
		spinLock(&BigLocksLock);
		if(BigLock->First->ID != id && BigLock->First->Locked)
			break;
		spinUnlock(&BigLocksLock);

	}
}

/*
void spinLockInit(spinLock_t *lock)
{
	*lock = SPIN_LOCK_INITIALIZER;
}
*/

void spinLock(spinLock_t *lock)
{
	while (lock->Locked != 0);
}

void spinUnlock(spinLock_t *lock)
{
	*lock->Locked = 0x0;
}

/*
int spinTryLock(spinLock_t *lock)
{
	register int locked;
	asm volatile("xchgl %0, %1"
		: "=&r" (locked), "=m" (*lock) : "0" (1)
	);
	return(!locked);
}


void spinLock_scheduler(spinLock_t *lock)
{
	while (*lock != 0);
}


int spinLockLocked(spinLock_t *lock)
{
	return(*lock != 0);
}
*/
 
/***
 END
 ***/

