/*
 * 	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 <linuxmt/types.h>
#include <linuxmt/sched.h>

/* This is used by the asm files */ 

__ptask CURRENT, NEXT;
__uint CURNUM;

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

	CURNUM = 2;

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

	task[maxproc].t_count = 0;
	CURNUM = maxproc;

	if (&task[CURNUM] != NEXT) {
		save_regs(NEXT);
		NEXT = &task[CURNUM];
		load_regs(NEXT);
	}
	schedule();
    }
}

__uint build_task()
{
	__ptask stask;
	__u16 tanum;

	tanum = alloc_task();
	stask = &task[tanum];
	stask->t_num = tanum;
	stask->t_begcode = stask->t_endcode = stask->t_begdata = stask->t_enddata = 0;
	stask->t_begstack = stask->t_endstack = 0;
	stask->t_regs.sp = stask->t_regs.ss = 0 ;
	stask->t_state = TASK_RUNNING;
	stask->t_count = stask->t_priority = 10;
	stask->t_flags = 0;
	stask->t_errno = 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;
}	
