/*

fiber.c - Fibers

*/

/*...sincludes:0:*/
#include <stdlib.h>
#include "types.h"
#include "interrupts.h"
#include "list.h"
#include "fiber.h"

/*...vtypes\46\h:0:*/
/*...vinterrupts\46\h:0:*/
/*...vlist\46\h:0:*/
/*...vfiber\46\h:0:*/
/*...e*/

static LIST fiber_list;
static BOOLEAN fiber_draining = FALSE;

/*...sfiber_init:0:*/
void fiber_init(void)
	{
	list_init(&fiber_list);
	}
/*...e*/
/*...sfiber_enqueue:0:*/
void fiber_enqueue(FIBER *f)
	{
	interrupts_disable();
	list_add_last(&fiber_list, f);
	interrupts_enable();
	}
/*...e*/
/*...sfiber_drainer:0:*/
static void fiber_drainer(void)
	{
	FIBER *f;
	fiber_draining = TRUE;
	while ( (f = list_remove_first(&fiber_list)) != NULL )
		{
		interrupts_enable();
		f->nf(f->nfp);
		interrupts_disable();
		}
	fiber_draining = FALSE;
	}
/*...e*/
/*...sfiber_drain:0:*/
void fiber_drain(void)
	{
	interrupts_disable();
	fiber_drainer();
	interrupts_enable();
	}
/*...e*/
/*...sfiber_enqueue_isr:0:*/
void fiber_enqueue_isr(FIBER *f)
	{
	list_add_last(&fiber_list, f);
	}
/*...e*/
/*...sfiber_drain_isr:0:*/
void fiber_drain_isr(void)
	{
	if ( !fiber_draining )
		fiber_drainer();
	}
/*...e*/
