#include <u.h>
#include <signal.h>
#include <errno.h>
#include "threadimpl.h"

//static Thread	*runthread(Proc*);

static char *_psstate[] = {
	"Dead",
	"Running",
	"Ready",
	"Rendezvous",
};

static char*
psstate(int s)
{
	if(s < 0 || s >= nelem(_psstate))
		return "unknown";
	return _psstate[s];
}

void
_schedinit(void *arg)
{
	Proc *p;
	Thread *t;
	extern void ignusr1(int), _threaddie(int);
	ignusr1(1);
	signal(SIGTERM, _threaddie);
  
	p = arg;
	lock(&p->lock);
	p->pid = _threadgetpid();
	_threadsetproc(p);
	unlock(&p->lock);
	while(_setlabel(&p->sched))
		;
malloc(10);
	_threaddebug(DBGSCHED, "top of schedinit, _threadexitsallstatus=%p", _threadexitsallstatus);
	if(_threadexitsallstatus)
		_exits(_threadexitsallstatus);
	lock(&p->lock);
	if((t=p->thread) != nil){
		p->thread = nil;
		if(t->moribund){
			if(t->moribund != 1)
				fprint(2, "moribund %d\n", t->moribund);
			assert(t->moribund == 1);
			t->state = Dead;
			if(t->prevt)
				t->prevt->nextt = t->nextt;
			else
				p->threads.head = t->nextt;
			if(t->nextt)
				t->nextt->prevt = t->prevt;
			else
				p->threads.tail = t->prevt;
			unlock(&p->lock);
			if(t->inrendez){
				abort();
			//	_threadflagrendez(t);
			//	_threadbreakrendez();
			}
			_stackfree(t->stk);
			free(t->cmdname);
			free(t);	/* XXX how do we know there are no references? */
			p->nthreads--;
			t = nil;
			_sched();
		}
/*
		if(p->needexec){
			t->ret = _schedexec(&p->exec);
			p->needexec = 0;
		}
*/
		if(p->newproc){
			t->ret = _schedfork(p->newproc);
			if(t->ret < 0){
//fprint(2, "_schedfork: %r\n");
				abort();
}
			p->newproc = nil;
		}
		t->state = t->nextstate;
		if(t->state == Ready)
			_threadready(t);
	}
	unlock(&p->lock);
	_sched();
}

static Thread*
runthread(Proc *p)
{
	Channel *c;
	Thread *t;
	Tqueue *q;
	Waitmsg *w;
	int e, sent;

	if(p->nthreads==0 || (p->nthreads==1 && p->idle))
		return nil;
	q = &p->ready;
relock:
	lock(&p->readylock);
	if(p->nsched%128 == 0){
		/* clean up children */
		e = errno;
		if((c = _threadwaitchan) != nil){
			if(c->n <= c->s){
				sent = 0;
				for(;;){
					if((w = p->waitmsg) != nil)
						p->waitmsg = nil;
					else
						w = waitnohang();
					if(w == nil)
						break;
					if(sent == 0){
						unlock(&p->readylock);
						sent = 1;
					}
					if(nbsendp(c, w) != 1)
						break;
				}
				p->waitmsg = w;
				if(sent)
					goto relock;
			}
		}else{
			while((w = waitnohang()) != nil)
				free(w);
		}
		errno = e;
	}
	if(q->head == nil){
		if(p->idle){
			if(p->idle->state != Ready){
				fprint(2, "everyone is asleep\n");
				exits("everyone is asleep");
			}
			unlock(&p->readylock);
			_threaddebug(DBGSCHED, "running idle thread", p->nthreads);
			return p->idle;
		}

		_threaddebug(DBGSCHED, "sleeping for more work (%d threads)", p->nthreads);
		q->asleep = 1;
		unlock(&p->readylock);
		while(rendezvous((ulong)q, 0) == ~0){
			if(_threadexitsallstatus)
				_exits(_threadexitsallstatus);
		}
		/* lock picked up from _threadready */
	}
	t = q->head;
	q->head = t->next;
	unlock(&p->readylock);
	return t;
}

void
needstack(int howmuch)
{
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	if(p == nil || (t=p->thread) == nil)
		return;
	if((ulong)&howmuch < (ulong)t->stk+howmuch){	/* stack overflow waiting to happen */
		fprint(2, "stack overflow: stack at 0x%lux, limit at 0x%lux, need 0x%lux\n", (ulong)&p, (ulong)t->stk, howmuch);
		abort();
	}
}

int
_sched(void)
{
	Proc *p;
	Thread *t;

Resched:
	p = _threadgetproc();
//fprint(2, "p %p\n", p);
malloc(10);
	if((t = p->thread) != nil){
		needstack(512);
	//	_threaddebug(DBGSCHED, "pausing, state=%s set %p goto %p",
	//		psstate(t->state), &t->sched, &p->sched);
print("swap\n");
		if(_setlabel(&t->sched)==0)
			_gotolabel(&p->sched);
		_threadstacklimit(t->stk, t->stk+t->stksize);
		return p->nsched++;
	}else{
malloc(10);
		t = runthread(p);
		if(t == nil){
			_threaddebug(DBGSCHED, "all threads gone; exiting");
			_threaddelproc();
			_schedexit(p);
		}
		_threaddebug(DBGSCHED, "running %d.%d", t->proc->pid, t->id);
		p->thread = t;
		if(t->moribund){
			_threaddebug(DBGSCHED, "%d.%d marked to die");
			goto Resched;
		}
		t->state = Running;
		t->nextstate = Ready;
malloc(10);
print("gotolabel\n");
		_gotolabel(&t->sched);
		for(;;);
	}
}

long
threadstack(void)
{
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	t = p->thread;
	return (ulong)&p - (ulong)t->stk;
}

void
_threadready(Thread *t)
{
	Tqueue *q;

	if(t == t->proc->idle){
		_threaddebug(DBGSCHED, "idle thread is ready");
		return;
	}

	assert(t->state == Ready);
	_threaddebug(DBGSCHED, "readying %d.%d", t->proc->pid, t->id);
	q = &t->proc->ready;
	lock(&t->proc->readylock);
	t->next = nil;
	if(q->head==nil)
		q->head = t;
	else
		q->tail->next = t;
	q->tail = t;
	if(q->asleep){
		assert(q->asleep == 1);
		q->asleep = 0;
		/* lock passes to runthread */
		_threaddebug(DBGSCHED, "waking process %d", t->proc->pid);
		while(rendezvous((ulong)q, 0) == ~0){
			if(_threadexitsallstatus)
				_exits(_threadexitsallstatus);
		}
	}else
		unlock(&t->proc->readylock);
}

void
_threadidle(void)
{
	Tqueue *q;
	Thread *t, *idle;
	Proc *p;

	p = _threadgetproc();
	q = &p->ready;
	lock(&p->readylock);
	assert(q->tail);
	idle = q->tail;
	if(q->head == idle){
		q->head = nil;
		q->tail = nil;
	}else{
		for(t=q->head; t->next!=q->tail; t=t->next)
			;
		t->next = nil;
		q->tail = t;
	}
	p->idle = idle;
	_threaddebug(DBGSCHED, "p->idle is %d\n", idle->id);
	unlock(&p->readylock);
}

int
yield(void)
{
	Proc *p;
	int nsched;

	p = _threadgetproc();
	nsched = p->nsched;
	return _sched() - nsched;
}

void
threadstatus(void)
{
	Proc *p;
	Thread *t;

	p = _threadgetproc();
	for(t=p->threads.head; t; t=t->nextt)
		fprint(2, "[%3d] %s userpc=%lux\n",
			t->id, psstate(t->state), t->userpc);
}
	
