File: [local] / funnyos / kern / kern_sched.c (download)
Revision 1.2, Tue Nov 20 16:07:24 2007 UTC (16 years, 7 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);
}