#include <9pm/u.h>
#include <9pm/libc.h>
#include <9pm/ns.h>
#include <9pm/thread.h>
#include <9pm/threadimpl.h>

void
yield(void)
{
	Thread *new, *t;
	Tproc *p;
	ulong thr;

	p = _threadgetproc();
	threadassert(p != nil);
	t = p->curthread;
	threadassert(t != nil);
	if (t->exiting) {
		_threaddebug(DBGTHRD|DBGKILL, "Exiting in yield()");
		threadexits(nil);	/* no return */
	}
	if ((new = _threadgetq(&p->runnable)) == nil) {
		_threaddebug(DBGTHRD, "Nothing to yield for");
		return;	/* Nothing to yield for */
	}
	_threadputq(&p->runnable, p->curthread);
	p->curthread->state = Runnable;
	_threaddebug(DBGTHRD, "Yielding to %d.%d", p->pid, new->id);
	p->curthread = new;
	new->state = Running;
	thr = _threadswtch(t->env, new->env, ~0);
	if (thr != ~0)
		_freethread((Thread *)thr);
	if (_threadgetthr()->exiting)
		threadexits(nil);
}

