diff --git a/src/sys/kernel/sched.c b/src/sys/kernel/sched.c index a4ab765..cadc822 100644 --- a/src/sys/kernel/sched.c +++ b/src/sys/kernel/sched.c @@ -53,6 +53,7 @@ prioQueue_t *prioLevels[MAXPRIOLEVELS - 1]; prioQueue_t *prioQStart = 0x0; +prioQueue_t *prioQEnd = 0x0; prioQueue_t *_currentQueue = 0x0; @@ -73,39 +74,62 @@ schedInit() { int i; - kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); - if (tmpTask == 0x0) { - kpanic("Error: kmalloc failed trying to initialize the task list\n"); - return(0x1); - } - - /* Set up the defaults for the initial task */ - tmpTask->prev = 0x0; - tmpTask->next = 0x0; - tmpTask->id = nextID++; - tmpTask->state = DEAD; - tmpTask->nice = MAXPRIOLEVELS/2 + 1; - _current = tmpTask; - - /* Allocating memory for the priority queues */ for (i = 0; i < MAXPRIOLEVELS; i++) { prioQueue_t *tmpPrioQ; - + kTask_t *tmpTask; + tmpPrioQ = (prioQueue_t *)kmalloc(sizeof(prioQueue_t)); - tmpPrioQ->start = 0x0; + tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); + + if (tmpPrioQ == 0x0) { + kpanic("Error: schedInit() - kmalloc failed trying to initialize a prioQueue_t struct\n"); + return(0x1); + } + + if (tmpTask == 0x0) { + kpanic("Error: schedInit() - kmalloc failed trying to initialize a kTask_t struct\n"); + return(0x1); + } + + tmpPrioQ->start = tmpTask; + tmpPrioQ->end = tmpTask; tmpPrioQ->prio = i; - prioLevels[i] = tmpPrioQ; - if (prioQStart == 0) tmpPrioQ->next = 0x0; - else tmpPrioQ->next = prioQStart; - prioQStart = tmpPrioQ; + prioLevels[i] = tmpPrioQ; + + tmpTask->prev = 0x0; + tmpTask->next = 0x0; + tmpTask->id = -1; + tmpTask->state = PLACEHOLDER; + tmpTask->nice = i; + tmpTask->timeSlice = systemVitals->dQuantum; + + /* Linking the previous placeholder with the current one */ + if (i > 0) { + prioLevels[i - 1]->start->next = tmpTask; + tmpTask->prev = prioLevels[i - 1]->end; + } + + if (0x0 == prioQStart) { + tmpPrioQ->next = 0x0; + tmpPrioQ->prev = 0x0; + prioQStart = prioQEnd = tmpPrioQ; + } else { + tmpPrioQ->prev = prioQEnd; + prioQEnd->next = tmpPrioQ; + tmpPrioQ->next = 0x0; + prioQEnd = tmpPrioQ; + } } - taskList = prioLevels[tmpTask->nice]->start = tmpTask; - _currentQueue = prioLevels[tmpTask->nice]; + taskList = prioLevels[0]->start; + _current = prioLevels[MAXPRIOLEVELS/2]->start; + _currentQueue = prioLevels[0]; + + nextID++; /* Print out information on scheduler */ - kprintf("sched0 solar - Address: [0x%X]\n", prioQStart); + kprintf("sched0 solar 0.2.1 - Address: [0x%X]\n", prioQStart); /* Return so we know everything went well */ return(0x0); @@ -135,30 +159,20 @@ } } - /* Finished all the tasks from the current prio queue */ + /* Finished all the tasks, restarting the list */ if (0x0 == tmpTask) { - /* Moving to the next queue which contains tasks */ - do { - if (0x0 == _currentQueue->next) - _currentQueue = prioQStart; - else - _currentQueue = _currentQueue->next; - } while (_currentQueue->start == 0x0); - - _current = _currentQueue->start; + _current = taskList; goto schedStart; } - + /* Setting the timeslice this task is allowed to run */ systemVitals->quantum = _current->timeSlice; memAddr = (uInt32)&(_current->tss); if (_current->state > 0x0) { - if (_current->oInfo.v86Task == 0x1) { - //kprintf("v86Task\n"); + if (_current->oInfo.v86Task == 0x1) irqDisable(0x0); - } - + ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF); ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); ubixGDT[4].descriptor.baseHigh = (memAddr >> 24); @@ -179,33 +193,38 @@ schedNewTask() { kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); - kTask_t *ll = 0x0; + + if (tmpTask == 0x0) { + kpanic("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n"); + return(0x0); + } + spinLock(&schedTaskSpinLock); /* Filling in tasks attrs */ - tmpTask->usedMath = 0x0; - tmpTask->id = nextID++; - tmpTask->state = NEW; - tmpTask->nice = _current->nice; - tmpTask->timeSlice = systemVitals->dQuantum * tmpTask->nice; - //tmpTask->oInfo.container = findMount("s"); <- No idea what this is - tmpTask->oInfo.cwd = (char *)kmalloc(1024); - - /* Looking for a place in the proper prio queue to place the task */ - for (ll = prioLevels[_current->nice]->start; ll; ll = ll->next) { - if (0x0 == ll->next) { - tmpTask->next = 0x0; - ll->next = tmpTask; - break; - } - } + tmpTask->usedMath = 0x0; + tmpTask->id = ++nextID; + tmpTask->state = NEW; + tmpTask->nice = _current->nice; - /* This prio queue has no task in it */ - if (0x0 == ll) { + tmpTask->timeSlice = systemVitals->dQuantum * tmpTask->nice; + tmpTask->oInfo.cwd = (char *)kmalloc(1024); + + /* Are we adding a task at the end of the last prio queue? */ + if (0x0 == prioLevels[_current->nice]->next) tmpTask->next = 0x0; - prioLevels[_current->nice]->start = tmpTask; - } - + else + tmpTask->next = prioLevels[_current->nice + 1]->start; + + tmpTask->prev = prioLevels[_current->nice]->end; + + /* + * Inserting the task at the end of the proper prio queue; + * this gives me the feeling of O(1) for task insertion + */ + prioLevels[_current->nice]->end->next = tmpTask; + prioLevels[_current->nice]->end = tmpTask; + spinUnlock(&schedTaskSpinLock); return(tmpTask); } @@ -220,26 +239,19 @@ schedDeleteTask(uInt32 id) { kTask_t *tmpTask = 0x0; - prioQueue_t *pQ = 0x0; spinLock(&schedTaskSpinLock); - - /* Checking each prio queue */ - for (pQ = prioQStart; pQ; pQ = pQ->next) { - - /* Checking each task from the prio queue */ - for (tmpTask = pQ->start; tmpTask; tmpTask = tmpTask->next) { - if (tmpTask->id == id) { - tmpTask->prev->next = tmpTask->next; - - /* We resort back to the initial task*/ - if (_current == tmpTask) { - _current == taskList; - } + /* Checking each task from the prio queue */ + for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) { + if (tmpTask->id == id) { + tmpTask->prev->next = tmpTask->next; + + if (_current == tmpTask) { + _current == tmpTask->next; } } } - + kfree(tmpTask); spinUnlock(&schedTaskSpinLock); return(0x0); @@ -250,14 +262,10 @@ schedFindTask(uInt32 id) { kTask_t *tmpTask = 0x0; - prioQueue_t *pQ = 0x0; - for (pQ = prioQStart; pQ; pQ = pQ->next) { - for (tmpTask = pQ->start; tmpTask; tmpTask = tmpTask->next) { - if (tmpTask->id == id) { - return(tmpTask); - } - } + for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) { + if (tmpTask->id == id) + return(tmpTask); } return(0x0); @@ -299,6 +307,9 @@ /*** $Log$ + Revision 1.10 2004/06/18 13:05:47 solar + Changed the scheduler by adding the first rudiments of priority; vitals.c initializes the system's default quantum to 40 + Revision 1.9 2004/06/04 13:29:56 reddawg libc: modified mkdir(); interface kpanic: kPanic(); now says kPanic: %s