diff --git a/src/sys/kernel/sched.c b/src/sys/kernel/sched.c index cedad83..a4ab765 100644 --- a/src/sys/kernel/sched.c +++ b/src/sys/kernel/sched.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,12 @@ kTask_t *_current = 0x0; kTask_t *_usedMath = 0x0; + +prioQueue_t *prioLevels[MAXPRIOLEVELS - 1]; +prioQueue_t *prioQStart = 0x0; +prioQueue_t *_currentQueue = 0x0; + + /************************************************************************ Function: int schedInit() @@ -60,138 +67,202 @@ 02/20/2004 - Approved for quality ************************************************************************/ -int schedInit() { - - /* Allocate memory for task list */ - taskList = (kTask_t *)kmalloc(sizeof(kTask_t)); - if (taskList == 0x0) { - kpanic("Error: kmalloc failed for taskList\n"); - return(0x1); - } - - /* Set up the defaults for the initial task. */ - taskList->prev = 0x0; - taskList->next = 0x0; - taskList->id = nextID++; - taskList->state = DEAD; - _current = taskList; - - /* Print out information on scheduler */ - kprintf("sched0 - Address: [0x%X]\n",taskList); - - /* Return so we know everything went well */ - return(0x0); - } - -void sched() { - uInt32 memAddr = 0x0; - kTask_t *tmpTask = 0x0; - struct tssStruct *gpfTSS = (struct tssStruct *)0x4200; - - spinLock(&schedSpinLock); - - gpfTSS->eip = (unsigned int)&_int13; - gpfTSS->esp = 0x1CFFF; - gpfTSS->ebp = 0x1CFFF; - gpfTSS->eflags = 0x206; -schedStart: - for (tmpTask=_current->next;tmpTask;tmpTask=tmpTask->next) { +int +schedInit() +{ + int i; + kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); - if (tmpTask->state > 0x0) { - _current = tmpTask; - break; - } /* if tmpTask->state > 0x0 */ - } /* for */ + 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; - if (0x0 == tmpTask) { - _current = taskList; - goto schedStart; - } /* if 0x0 == tmpTask */ + /* Allocating memory for the priority queues */ + for (i = 0; i < MAXPRIOLEVELS; i++) { + prioQueue_t *tmpPrioQ; - memAddr = (uInt32)&(_current->tss); + tmpPrioQ = (prioQueue_t *)kmalloc(sizeof(prioQueue_t)); + tmpPrioQ->start = 0x0; + tmpPrioQ->prio = i; + prioLevels[i] = tmpPrioQ; + if (prioQStart == 0) tmpPrioQ->next = 0x0; + else tmpPrioQ->next = prioQStart; + prioQStart = tmpPrioQ; + } - if (_current->state > 0x0) { - if (_current->oInfo.v86Task == 0x1) { - //kprintf("v86Task\n"); - irqDisable(0x0); - } - ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF); - ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); - ubixGDT[4].descriptor.baseHigh = (memAddr >> 24); - ubixGDT[4].descriptor.access = '\x89'; - spinUnlock(&schedSpinLock); - asm("ljmp $0x20,$0\n"); - } - spinUnlock(&schedSpinLock); - return; - } /* sched() */ + taskList = prioLevels[tmpTask->nice]->start = tmpTask; + _currentQueue = prioLevels[tmpTask->nice]; -kTask_t *schedNewTask() { - kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); - kTask_t *listLoop = 0x0; - - spinLock(&schedTaskSpinLock); - - for (listLoop = taskList; listLoop; listLoop = listLoop->next) { - - if (0x0 == listLoop->next) { - tmpTask->prev = listLoop; - tmpTask->next = 0x0; - listLoop->next = tmpTask; - break; - } /* if listLoop->next == 0x0 */ - - } /* for */ - - tmpTask->usedMath = 0x0; - tmpTask->id = nextID++; - tmpTask->state = NEW; - //tmpTask->oInfo.container = findMount("s"); - tmpTask->oInfo.cwd = (char *)kmalloc(1024); - - spinUnlock(&schedTaskSpinLock); - return(tmpTask); - } /* schedNewTask() */ - -int schedDeleteTask(uInt32 id) { - kTask_t *tmpTask = 0x0; - - spinLock(&schedTaskSpinLock); - - for (tmpTask = taskList; tmpTask; tmpTask=tmpTask->next) { - - if (tmpTask->id == id) { - - tmpTask->prev->next = tmpTask->next; - tmpTask->next->prev = tmpTask->prev; - - if (_current == tmpTask) { - _current = taskList; - } /* if _current == tmpTask */ - - kfree(tmpTask); - - } /* if tmpTask-> == id */ - } /* for */ - - spinUnlock(&schedTaskSpinLock); - return(0); - } /* deleteTask() */ + /* Print out information on scheduler */ + kprintf("sched0 solar - Address: [0x%X]\n", prioQStart); + + /* Return so we know everything went well */ + return(0x0); +} -kTask_t *schedFindTask(uInt32 id) { - kTask_t *tmpTask = 0x0; - for (tmpTask = taskList; tmpTask != 0x0; tmpTask = tmpTask->next) { +void +sched() +{ + uInt32 memAddr = 0x0; + kTask_t *tmpTask = 0x0; + struct tssStruct *gpfTSS = (struct tssStruct *)0x4200; - if (tmpTask->id == id) { - return(tmpTask); - } /* if tmpTask-> == id */ + spinLock(&schedSpinLock); - } /* for */ - return(0x0); - } /* findTask() */ + gpfTSS->eip = (unsigned int)&_int13; + gpfTSS->esp = 0x1CFFF; + gpfTSS->ebp = 0x1CFFF; + gpfTSS->eflags = 0x206; + + schedStart: + /* Yield the next task from the current prio queue */ + for (tmpTask = _current->next; tmpTask; tmpTask = tmpTask->next) { + if (tmpTask->state > 0x0) { + _current = tmpTask; + break; + } + } + + /* Finished all the tasks from the current prio queue */ + 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; + 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"); + irqDisable(0x0); + } + + ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF); + ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); + ubixGDT[4].descriptor.baseHigh = (memAddr >> 24); + ubixGDT[4].descriptor.access = '\x89'; + + spinUnlock(&schedSpinLock); + + asm("ljmp $0x20,$0\n"); + } + + spinUnlock(&schedSpinLock); + + return; +} + + +kTask_t * +schedNewTask() +{ + kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); + kTask_t *ll = 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; + } + } + + /* This prio queue has no task in it */ + if (0x0 == ll) { + tmpTask->next = 0x0; + prioLevels[_current->nice]->start = tmpTask; + } + + spinUnlock(&schedTaskSpinLock); + return(tmpTask); +} + + +/* + * This is at least O(N)... it was written to + * have it functional; soon it will be changed to O(1). + */ + +int +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; + } + } + } + } + + kfree(tmpTask); + spinUnlock(&schedTaskSpinLock); + return(0x0); +} + + +kTask_t * +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); + } + } + } + + return(0x0); +} + /************************************************************************ @@ -204,10 +275,11 @@ 02/20/2004 - Approved for quality ************************************************************************/ -void schedEndTask(pidType pid) { - endTask(_current->id); - schedYield(); - } +void +schedEndTask(pidType pid) { + endTask(_current->id); + schedYield(); +} /************************************************************************ @@ -220,12 +292,19 @@ 02/20/2004 - Approved for quality ************************************************************************/ -void schedYield() { - sched(); - } +void +schedYield() { + sched(); +} /*** $Log$ + Revision 1.9 2004/06/04 13:29:56 reddawg + libc: modified mkdir(); interface + kpanic: kPanic(); now says kPanic: %s + system: now reboots when receives message for reboot + also when command start sde is received by system the STD is started + Revision 1.8 2004/05/25 16:10:46 reddawg Spin Locks @@ -247,4 +326,3 @@ END ***/ - diff --git a/src/sys/kernel/vitals.c b/src/sys/kernel/vitals.c index 3292299..4fba026 100644 --- a/src/sys/kernel/vitals.c +++ b/src/sys/kernel/vitals.c @@ -59,6 +59,7 @@ systemVitals->sysTicks = 0x0; systemVitals->sysUptime = 0x0; systemVitals->quantum = 40; + systemVitals->dQuantum = 40; systemVitals->fileSystems = 0x0; systemVitals->mountPoints = 0x0; systemVitals->timeStart = 0x0; @@ -75,6 +76,10 @@ /*** $Log$ + Revision 1.5 2004/06/16 12:04:18 reddawg + systemVitals->quantum = (1000/msPerQuantum) + The timer int now will call scheduler at the rate of the defined quantum + Revision 1.4 2004/06/15 12:24:07 reddawg Cleaned Up