#include "threadimpl.h"

Pqueue _threadpq;	/* list of all procs */
int _threadnprocs;	/* count of procs */

static int newthreadid(void);
static int newprocid(void);

/*
 * Create and initialize a new Thread structure attached to a given proc.
 */
int
_newthread(Proc *p, void (*f)(void *arg), void *arg, uint stacksize, 
	char *name, int grp)
{
	int id;
	Thread *t;

	t = _threadmalloc(sizeof(Thread), 1);
	t->proc = p;
	t->nextproc = p;
	t->homeproc = p;

	t->grp = grp;
	t->id = id = newthreadid();
	if(name)
		t->name = strdup(name);
	_threaddebug(DBGSCHED, "create thread %d.%d name %s", p->id, id, name);

	/*
	 * Allocate and clear stack.
	 */
	if(stacksize < 1024)
		sysfatal("bad stacksize %d", stacksize);
	t->stk = _threadmalloc(stacksize, 0);
	t->stksize = stacksize;
	_threaddebugmemset(t->stk, 0xFE, stacksize);

	/*
	 * Set up t->context to call f(arg).
	 */
	_threadinitstack(t, f, arg);

	/*
	 * Add thread to proc.
	 */
	lock(&p->lock);
	_procaddthread(p, t);

	/*
	 * Mark thread as ready to run.
	 */
	t->state = Ready;
	_threadready(t);
	unlock(&p->lock);

	return id;
}

/* 
 * Free a Thread structure.
 */
void
_threadfree(Thread *t)
{
	free(t->stk);
	free(t->name);
	free(t);
}

/*
 * Create and initialize a new Proc structure with a single Thread
 * running inside it.  Add the Proc to the global process list.
 */
Proc*
_newproc(void)
{
	Proc *p;

	/*
	 * Allocate.
	 */
	p = _threadmalloc(sizeof *p, 1);
	p->id = newprocid();
	
	/*
	 * Add to list.  Record if we're now multiprocess.
	 */
	lock(&_threadpq.lock);
	if(_threadpq.head == nil)
		_threadpq.head = p;
	else
		*_threadpq.tail = p;
	_threadpq.tail = &p->next;
	if(_threadnprocs == 1)
		_threadmultiproc();
	_threadnprocs++;
	unlock(&_threadpq.lock);

	return p;
}

/*
 * Allocate a new thread running f(arg) on a stack of size stacksize.
 * Return the thread id.  The thread group inherits from the current thread.
 */
int
threadcreate(void (*f)(void*), void *arg, uint stacksize)
{
	return _newthread(_threadgetproc(), f, arg, stacksize, nil, threadgetgrp());
}

/* 
 * Allocate a new idle thread.  Only allowed in a single-proc program.
 */
int
threadcreateidle(void (*f)(void *arg), void *arg, uint stacksize)
{
	int id;

	assert(_threadpq.head->next == nil);	/* only 1 */

	id = threadcreate(f, arg, stacksize);
	_threaddebug(DBGSCHED, "idle is %d", id);
	_threadsetidle(id);
	return id;
}

/*
 * Threadcreate, but do it inside a fresh proc.
 */
int
proccreate(void (*f)(void*), void *arg, uint stacksize)
{
	int id;
	Proc *p, *np;

	p = _threadgetproc();
	np = _newproc();
	p->newproc = np;
	p->schedfn = _kthreadstartproc;
	id = _newthread(np, f, arg, stacksize, nil, p->thread->grp);
	_sched();	/* call into scheduler to create proc XXX */
	return id;
}

/*
 * Allocate a new thread id.
 */
static int
newthreadid(void)
{
	static Lock l;
	static int id;
	int i;

	lock(&l);
	i = ++id;
	unlock(&l);
	return i;
}

/*
 * Allocate a new proc id.
 */
static int
newprocid(void)
{
	static Lock l;
	static int id;
	int i;

	lock(&l);
	i = ++id;
	unlock(&l);
	return i;
}

/*
 * Add thread to proc's list.
 */
void
_procaddthread(Proc *p, Thread *t)
{
	p->nthreads++;
	if(p->threads.head == nil)
		p->threads.head = t;
	else{
		t->prevt = p->threads.tail;
		t->prevt->nextt = t;
	}
	p->threads.tail = t;
	t->next = (Thread*)~0;
}

/*
 * Remove thread from proc's list.
 */
void
_procdelthread(Proc *p, Thread *t)
{
	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;
	p->nthreads--;
}
