[BACK]Return to kern_sched.c CVS log [TXT][DIR] Up to [local] / funnyos / kern

File: [local] / funnyos / kern / kern_sched.c (download)

Revision 1.2, Tue Nov 20 16:07:24 2007 UTC (16 years, 5 months ago) by nbrk
Branch: MAIN
Changes since 1.1: +123 -1 lines

implement sched_init();

/*
 * $Id: kern_sched.c,v 1.2 2007/11/20 16:07:24 nbrk Exp $
 */
#include <sys/types.h>
#include <sys/kern_sched.h>
#include <sys/kern_time.h> /* for HZ */
#include <sys/mem.h>

#include <libkern/printf.h>


/* config.c gives us tasks that we'll schedule */
extern struct u_task config_tasklist[];

/* list of k_tasks */
struct k_task *ktasklist;

/* pcb of running task; we will save context there when enter irq_mode */
uint32_t *curpcb;

/* total tasks; used to TID generation */
uint8_t ntasks;

/* "idle" task exists forever and occupy cpu when there is no other task pretending. */
const struct u_task idle_utask = {"idle", 0, NULL};


void
sched_init(void)
{
	/*
	 * Create struct k_task for each u_task that user described in config_tasklist.
	 */
	struct u_task *utaskp;
	struct k_task *ktaskp, *oldktaskp;

	ntasks = 0;

	/*
	 * Create an "idle" task which always has TID 0.
	 */
	ktaskp = kmalloc(sizeof(struct k_task));

	if (ktaskp == NULL)
		panic("can't allocate memory for idle task\n");

	/* link u_task for idle task */
	ktaskp->kt_utask = (struct u_task *)&idle_utask;

	/* TID (always 0) */
	ktaskp->kt_tid = 0;

	/* idle task is always in state READY (or RUNNING, if on processor now) */
	ktaskp->kt_state = TASK_READY;

	/* next task in list isn't up yet (and prev too) */
	ktaskp->kt_next = NULL;

	/* make "idle" task first task in ktasklist, system k_task list */
	ktasklist = ktaskp;

	/* bump ntasks to 1 */
	ntasks = 1;

	/* preserve pointer to this k_task so we can link-in next task */
	oldktaskp = ktaskp;

	/*
	 * Idle task set up completed.
	 * Configure all other system tasks,
	 */

	/* look through tasklist */
	utaskp = config_tasklist;
	while(utaskp->ut_name != NULL) {

		/* try to allocate memory for ktask */
		ktaskp = kmalloc(sizeof(struct k_task));

		if (ktaskp == NULL)
			panic("can't allocate memory for task '%s'\n", utaskp->ut_name);

		/*
		 * Successfully allocated new ktask.
		 */

		/* link u_task */
		ktaskp->kt_utask = utaskp;

		/* set TID (Task Identificator) */
		ktaskp->kt_tid = oldktaskp->kt_tid + 1;

		/* state */
		ktaskp->kt_state = TASK_READY;

		/* link current task in previous task's structure */
		oldktaskp->kt_next = ktaskp;

		/* NULLify kt_next of current task */
		ktaskp->kt_next = NULL;

		/* save current ktask for use with next ktask */
		oldktaskp = ktaskp;

		/* bump ntasks */
		ntasks++;

		/* shift to next element in config_tasklist[] */
		utaskp++;
	}

	/* make this list circularly linked (e.g point list's last->next node into first) */
	ktaskp->kt_next = ktasklist;

	printf("kern_sched: created %d tasks:", ntasks);

	/* print tasks' names */
	ktaskp = ktasklist + 1; /* skip (first) "idle" task (display it as the end of circularly list) */
	do {
		printf(" %s", ktaskp->kt_utask->ut_name);

		if (ktaskp->kt_tid == NULL) /* that was an "idle" task */
			break;

		ktaskp = ktaskp->kt_next;
	} while(1);

	printf("; HZ=%d\n", HZ);

}