/*
 * 	kernel/sched.c
 * 	(C) 1995 Chad Page 
 *	
 *	This is the main scheduler - hopefully simpler than Linux's at present.
 * 
 * 	We need to implement run-queues RSN, but first we just have to make
 * 	it *work*.  Of course, writing it would be a good start :)
 *
 */

#include <linux16/types.h>
#include <linux16/sched.h>

/* This is used by the asm files */ 

__ptask CURRENT, NEXT;
__uint CURNUM;
__uint a;

void schedule_task()
{
	__uint maxpri; 
	__uint c; 
	__ptask pt, maxproc; 	/* Subscipt calculation is *very* expensive in bcc */

	CURNUM = SCHED_TNUM;
	while (1) {
		maxpri = maxproc = 0;
		for (c = FIRST_UTNUM; c < MAX_TASKS; c++) {
			pt = &task[c];
			if ((pt->t_state && TASK_RUNNING) && (pt->t_num == c)) {
				pt->t_count += pt->t_priority;
				if (pt->t_count > maxpri) {
					maxproc = pt;
					maxpri = pt->t_count;
				}
			}
		}

		maxproc->t_count = 0;
		CURNUM = maxproc->t_num;

		save_regs(NEXT);
		NEXT = maxproc;
		load_regs(NEXT);
		while (CURNUM > MAX_TASKS) {}; 
		schedule();
    	}
}

__uint build_task()
{
	__ptask stask;
	__u16 tanum;

	tanum = alloc_task();
	stask = &task[tanum];
	stask->t_num = tanum;
	stask->t_begcode = stask->t_endcode = 0; 
	stask->t_begdata = stask->t_enddata = 0;
	stask->t_begstack = stask->t_endstack = stask->t_begstack = stask->t_endstack = 0;
	stask->t_state = TASK_RUNNING;
	stask->t_count = stask->t_priority = 10;
	stask->t_errno = stask->t_flags = 0;

	return tanum; 
}

/* This loads a task into memory - the task given can be deleted, as it is
 * now in the kernel data structure */

__uint alloc_task()
{
	__uint count, found, b;

	found = 0;
	for (count = 0; (count < MAX_TASKS); count++) {
		if ((task[count].t_num != count)) {
			found = count;
			break;	
		}
	}			

	return found;
}	
