#include <lib9.h>

static struct {
	QLp	*p;
	QLp	x[1024];
} ql = {
	ql.x
};

enum
{
	Queuing,
	QueuingR,
	QueuingW,
	Sleeping,
	Waking,
};

static void (*procsleep)(_Procrend*) = _procsleep;
static void (*procwakeup)(_Procrend*) = _procwakeup;
#define _procsleep donotcall_procsleep
#define _procwakeup donotcall_procwakeup

/* this gets called by the thread library ONLY to get us to use its rendezvous */
void
_qlockinit(void (*sleep)(_Procrend*), void (*wakeup)(_Procrend*))
{
	procsleep = sleep;
	procwakeup = wakeup;
}

/* find a free shared memory location to queue ourselves in */
static QLp*
getqlp(void)
{
	QLp *p, *op;

	op = ql.p;
	for(p = op+1; ; p++){
		if(p == &ql.x[nelem(ql.x)])
			p = ql.x;
		if(p == op){
			fprint(2, "qlock: out of qlp\n");
			abort();
		}
		if(canlock(&p->inuse)){
			ql.p = p;
			p->next = nil;
			break;
		}
	}
	return p;
}

void
qlock(QLock *q)
{
	QLp *p, *mp;

	lock(&q->lock);
	if(!q->locked){
		q->locked = 1;
		unlock(&q->lock);
		return;
	}


	/* chain into waiting list */
	mp = getqlp();
	p = q->tail;
	if(p == nil)
		q->head = mp;
	else
		p->next = mp;
	q->tail = mp;
	mp->state = Queuing;
	mp->rend.l = &q->lock;
	procsleep(&mp->rend);
	unlock(&q->lock);
	assert(mp->state == Waking);
	unlock(&mp->inuse);
}

void
qunlock(QLock *q)
{
	QLp *p;

	lock(&q->lock);
	p = q->head;
	if(p != nil){
		/* wakeup head waiting process */
		q->head = p->next;
		if(q->head == nil)
			q->tail = nil;
		p->state = Waking;
		procwakeup(&p->rend);
		unlock(&q->lock);
		return;
	}
	q->locked = 0;
	unlock(&q->lock);
}

int
canqlock(QLock *q)
{
	if(!canlock(&q->lock))
		return 0;
	if(!q->locked){
		q->locked = 1;
		unlock(&q->lock);
		return 1;
	}
	unlock(&q->lock);
	return 0;
}

void
rlock(RWLock *q)
{
	QLp *p, *mp;

	lock(&q->lock);
	if(q->writer == 0 && q->head == nil){
		/* no writer, go for it */
		q->readers++;
		unlock(&q->lock);
		return;
	}

	mp = getqlp();
	p = q->tail;
	if(p == 0)
		q->head = mp;
	else
		p->next = mp;
	q->tail = mp;
	mp->next = nil;
	mp->state = QueuingR;
	mp->rend.l = &q->lock;
	procsleep(&mp->rend);
	unlock(&q->lock);
	assert(mp->state == Waking);
	unlock(&mp->inuse);
}

int
canrlock(RWLock *q)
{
	lock(&q->lock);
	if (q->writer == 0 && q->head == nil) {
		/* no writer; go for it */
		q->readers++;
		unlock(&q->lock);
		return 1;
	}
	unlock(&q->lock);
	return 0;
}

void
runlock(RWLock *q)
{
	QLp *p;

	lock(&q->lock);
	if(q->readers <= 0)
		abort();
	p = q->head;
	if(--(q->readers) > 0 || p == nil){
		unlock(&q->lock);
		return;
	}

	/* start waiting writer */
	if(p->state != QueuingW)
		abort();
	q->head = p->next;
	if(q->head == 0)
		q->tail = 0;
	q->writer = 1;

	/* wakeup waiter */
	p->state = Waking;
	procwakeup(&p->rend);
	unlock(&q->lock);
}

void
wlock(RWLock *q)
{
	QLp *p, *mp;

	lock(&q->lock);
	if(q->readers == 0 && q->writer == 0){
		/* noone waiting, go for it */
		q->writer = 1;
		unlock(&q->lock);
		return;
	}

	/* wait */
	p = q->tail;
	mp = getqlp();
	if(p == nil)
		q->head = mp;
	else
		p->next = mp;
	q->tail = mp;
	mp->next = nil;
	mp->state = QueuingW;

	/* wait in kernel */
	mp->rend.l = &q->lock;
	procsleep(&mp->rend);
	unlock(&q->lock);
	assert(mp->state == Waking);
	unlock(&mp->inuse);
}

int
canwlock(RWLock *q)
{
	lock(&q->lock);
	if (q->readers == 0 && q->writer == 0) {
		/* no one waiting; go for it */
		q->writer = 1;
		unlock(&q->lock);
		return 1;
	}
	unlock(&q->lock);
	return 0;
}

void
wunlock(RWLock *q)
{
	QLp *p;

	lock(&q->lock);
	if(q->writer == 0){
		fprint(2, "wunlock: not holding lock\n");
		abort();
	}
	p = q->head;
	if(p == nil){
		q->writer = 0;
		unlock(&q->lock);
		return;
	}
	if(p->state == QueuingW){
		/* start waiting writer */
		q->head = p->next;
		if(q->head == nil)
			q->tail = nil;
		p->state = Waking;
		procwakeup(&p->rend);
		unlock(&q->lock);
		return;
	}

	if(p->state != QueuingR){
		fprint(2, "wunlock: bad state\n");
		abort();
	}

	/* wake waiting readers */
	while(q->head != nil && q->head->state == QueuingR){
		p = q->head;
		q->head = p->next;
		q->readers++;
		p->state = Waking;
		procwakeup(&p->rend);
	}
	if(q->head == nil)
		q->tail = nil;
	q->writer = 0;
	unlock(&q->lock);
}

void
rsleep(Rendez *r)
{
	QLp *t, *me;

	if(!r->l){
		fprint(2, "rsleep: no lock\n");
		abort();
	}
	lock(&r->l->lock);
	/* we should hold the qlock */
	if(!r->l->locked){
		fprint(2, "rsleep: not locked\n");
		abort();
	}

	/* add ourselves to the wait list */
	me = getqlp();
	me->state = Sleeping;
	if(r->head == nil)
		r->head = me;
	else
		r->tail->next = me;
	me->next = nil;
	r->tail = me;

	/* pass the qlock to the next guy */
	t = r->l->head;
	if(t){
		r->l->head = t->next;
		if(r->l->head == nil)
			r->l->tail = nil;
		t->state = Waking;
		procwakeup(&t->rend);
	}else
		r->l->locked = 0;

	/* wait for a wakeup */
	me->rend.l = &r->l->lock;
	procsleep(&me->rend);
	assert(me->state == Waking);
	unlock(&me->inuse);
	if(!r->l->locked){
		fprint(2, "rsleep: not locked after wakeup\n");
		abort();
	}
	unlock(&r->l->lock);
}

int
rwakeup(Rendez *r)
{
	QLp *t;

	/*
	 * take off wait and put on front of queue
	 * put on front so guys that have been waiting will not get starved
	 */
	
	if(!r->l){
		fprint(2, "rwakeup: no lock\n");
		abort();
	}
	lock(&r->l->lock);
	if(!r->l->locked){
		fprint(2, "rwakeup: not locked\n");
		abort();
	}

	t = r->head;
	if(t == nil){
		unlock(&r->l->lock);
		return 0;
	}

	r->head = t->next;
	if(r->head == nil)
		r->tail = nil;

	t->next = r->l->head;
	r->l->head = t;
	if(r->l->tail == nil)
		r->l->tail = t;

	t->state = Queuing;
	unlock(&r->l->lock);
	return 1;
}

int
rwakeupall(Rendez *r)
{
	int i;

	for(i=0; rwakeup(r); i++)
		;
	return i;
}
