diff --git a/src/sys/include/ubixos/schedule.h b/src/sys/include/ubixos/schedule.h index ca5cdf7..17b70b6 100755 --- a/src/sys/include/ubixos/schedule.h +++ b/src/sys/include/ubixos/schedule.h @@ -26,7 +26,7 @@ #include -#define numTasks 1024 +extern int numTasks; /* #define RUNABLE 3 #define ACTIVE 2 #define INACTIVE 1 @@ -99,7 +99,7 @@ char fileImage[256]; } kTask_t; -extern kTask_t *taskList; +//extern kTask_t *taskList; extern kTask_t *_current,*_usedMath; extern int currentProc; @@ -107,6 +107,7 @@ void initScheduler(); kTask_t * findTask(); +kTask_t * getTask(int taskId); void timerInt(); void schedule(); @@ -140,5 +141,6 @@ void waitQueueInsert(waitQueue_t *, void *, int); void * waitQueueRemove(waitQueue_t *, int *); +void * waitQueueFind(waitQueue_t *, int); #endif diff --git a/src/sys/include/ubixos/spinlock.h b/src/sys/include/ubixos/spinlock.h index 7c11e3a..029bfc9 100755 --- a/src/sys/include/ubixos/spinlock.h +++ b/src/sys/include/ubixos/spinlock.h @@ -4,6 +4,9 @@ typedef struct __SPINLOCK_TYPE { + int count; // for recursion. + int owner; + int ticket[16]; // allow up to 16 CPUs. int choiceInProgress[16]; diff --git a/src/sys/kernel/schedule.c b/src/sys/kernel/schedule.c index b88a4e9..004b7e6 100755 --- a/src/sys/kernel/schedule.c +++ b/src/sys/kernel/schedule.c @@ -32,6 +32,8 @@ #include #include +#include + #ifndef CURRENT_CPU #define CURRENT_CPU 0 #endif @@ -39,7 +41,9 @@ const uint32_t schedMagicNumber = 0x253B9CF9; spinlock_t schedSpinlock; +waitQueue_t taskQueue; +int numTasks = 0; int currentProc = -1; int lastPid = -1; kTask_t *taskList = (kTask_t *)0xE0800000; @@ -58,7 +62,41 @@ schedule(); } +void kmemset(void * dest, char value, int size) +{ + size--; + while(size >= 0) + ((char *)dest)[size--] = value; +} + +void initScheduler(void) +{ + //kprintf(">>Init\n"); + + spinlockInit(&schedSpinlock); + waitQueueInit(&taskQueue, 0); + + // create -1 task. + + kTask_t * firstTask = kmalloc(sizeof(kTask_t)); + //kprintf("from malloc %08x\n", firstTask); + if (firstTask == NULL) + kpanic("Scheduler Init: Couldn't allocate first task"); + + firstTask->id = -1; + firstTask->status = EMPTY; + waitQueueInsert(&taskQueue, firstTask, firstTask->id); + + currentProc = -1; + _current = firstTask; + + //kprintf("<>FindTask\n"); + + kTask_t * newTask = kmalloc(sizeof(kTask_t)); + //kprintf("from malloc %08x\n", newTask); + if (newTask == NULL) + kpanic("Scheduler: Couldn't allocate memory for new task"); + + spinlockLock(&schedSpinlock, CURRENT_CPU); + + kmemset(newTask, '\0', sizeof(kTask_t)); + lastPid++; + newTask->id = lastPid; + newTask->status = EMPTY; + newTask->usedMath=0; + newTask->cpuTime = 0; + newTask->uid = -1; + newTask->gid = -1; + + numTasks++; + + waitQueueInsert(&taskQueue, newTask, newTask->id); + spinlockUnlock(&schedSpinlock, CURRENT_CPU); + + kprintf("<>getTask\n"); + + spinlockLock(&schedSpinlock, CURRENT_CPU); + temp = waitQueueFind(&taskQueue, taskId); + spinlockUnlock(&schedSpinlock, CURRENT_CPU); + + //kprintf("<>schedule\n"); + + outportByte(0x20, 0x20); + + if (paniced == 1) + while (1) + asm("nop;nop;nop;nop;nop"); + + if (numTasks == 0) + return; + spinlockLock(&schedSpinlock, CURRENT_CPU); + + chooseTask = currentProc + 1; + + while ((getTask(chooseTask)->status != READY) && + (getTask(chooseTask)->status != RUNNING) && (loopCount < 4)) + { + chooseTask++; + chooseTask %= numTasks; + if (chooseTask == 0) + loopCount++; + //kprintf("Trying: %d\n", chooseTask); + //kprintf("numtasks: %d\n", numTasks); + } + if (loopCount == 4) + chooseTask = -1; + kprintf("Found one %d\n", chooseTask); + if (chooseTask != -1) + { + if (getTask(chooseTask)->status == RUNNING) + { + getTask(chooseTask)->status = READY; + } + currentProc = chooseTask; + _current = getTask(chooseTask); + getTask(chooseTask)->status = RUNNING; + getTask(chooseTask)->cpuTime++; + memAddr = (uint32_t) &(getTask(chooseTask)->tss); + GDT[4].descriptor.baseLow = (memAddr & 0xFFFF); + GDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); + GDT[4].descriptor.baseHigh = (memAddr >> 24); + + //kprintf("Spinlock try\n"); + spinlockUnlock(&schedSpinlock, CURRENT_CPU); + //kprintf("Spinlock complete\n"); + + kprintf("<magic_number = schedMagicNumber; queue->type = type; @@ -171,10 +320,11 @@ void waitQueueInit(waitQueue_t * queue, int type) { - memset(queue, '\0', sizeof(*queue)); + kmemset(queue, '\0', sizeof(*queue)); queue->magic_number = schedMagicNumber; queue->type = type; + queue->first = queue->last = NULL; return; @@ -184,6 +334,8 @@ { struct waitQueueNode * temp; + //kprintf("Odd.\n"); + if (queue == NULL) return; @@ -197,7 +349,7 @@ kfree(temp); } - memset(queue, '\0', sizeof(waitQueue_t)); + kmemset(queue, '\0', sizeof(waitQueue_t)); kfree(queue); } @@ -205,6 +357,8 @@ { struct waitQueueNode * temp; + //kprintf("Odd.\n"); + if (queue->magic_number != schedMagicNumber) return; @@ -215,43 +369,57 @@ kfree(temp); } - memset(queue, '\0', sizeof(waitQueue_t)); + kmemset(queue, '\0', sizeof(waitQueue_t)); } void waitQueueInsert(waitQueue_t * queue, void * data, int id) { struct waitQueueNode * temp; + //kprintf("Here. %d\n", id); + if (queue == NULL) return; if (queue->magic_number != schedMagicNumber) return; - + + temp = NULL; temp = (struct waitQueueNode *) kmalloc(sizeof(struct waitQueueNode)); - memset(temp, '\0', sizeof(struct waitQueueNode)); + //kprintf("from malloc %08x\n", temp); + //kprintf("Ye.\n"); + kmemset(temp, '\0', sizeof(struct waitQueueNode)); + //kprintf("Yo.\n"); + temp->prev = temp->next = NULL; if (queue->first == NULL) { - queue->first = queue->last = temp; + kprintf("head was NULL.\n"); + queue->first = queue->last = temp; } else { queue->last->next = temp; - temp->prev = queue->last->next; + temp->prev = queue->last; queue->last = temp; } temp->data = data; temp->id = id; + kprintf("Queue head = %08x\n", queue->first); + kprintf("Queue tail = %08x\n", queue->last); + kprintf("Sizeof = %d\n", sizeof(waitQueue_t)); + return; } void * waitQueueRemove(waitQueue_t * queue, int * id) { void * temp; - + + //kprintf("Odd.\n"); + if (queue == NULL) return NULL; @@ -280,4 +448,38 @@ } +void * waitQueueFind(waitQueue_t * queue, int id) +{ + struct waitQueueNode * temp; + if (queue == NULL) + return NULL; + + if (queue->magic_number != schedMagicNumber) + return NULL; + + if (queue->first == NULL) + return NULL; + + temp = queue->first; + + //kprintf (">>while\n"); + + while ((temp->id != id) && (temp->next != NULL)) + { + //kprintf("id = %d\n", id); + //kprintf("temp->id: %d\n", temp->id); + //kprintf("temp->next: %08x\n", temp->next); + temp = temp->next; + } + //while(1) + // ; + + //kprintf("<id == id) + return temp; + + return NULL; +} + diff --git a/src/sys/kernel/spinlock.c b/src/sys/kernel/spinlock.c index 0bb6e51..7ba7b85 100755 --- a/src/sys/kernel/spinlock.c +++ b/src/sys/kernel/spinlock.c @@ -46,9 +46,15 @@ { int max_ticket = 0; int i; - + if (lock->deleteInProgress == 1) return SPINLOCK_FAIL_DELETING; + + if (lock->owner == cpuID) + { + lock->count++; + return SPINLOCK_SUCCESS; + } lock->choiceInProgress[cpuID] = 1; @@ -73,13 +79,24 @@ } + lock->owner = cpuID; + return SPINLOCK_SUCCESS; } int spinlockUnlock(spinlock_t * lock, int cpuID) { + if (lock->owner == cpuID) + { + lock->count--; + if (lock->count != 0) + { + return SPINLOCK_SUCCESS; + } + } lock->ticket[cpuID] = 0; + lock->owner = -1; return SPINLOCK_SUCCESS; } diff --git a/src/sys/kernel/syscall.c b/src/sys/kernel/syscall.c index 39ecb1f..43e053b 100755 --- a/src/sys/kernel/syscall.c +++ b/src/sys/kernel/syscall.c @@ -84,7 +84,7 @@ void sysCheckPid() { int *ptr; asm("": "=b" (ptr)); - if ((taskList[*ptr].status != STARTING) && (taskList[*ptr].status != EMPTY)) { + if ((getTask(*ptr)->status != STARTING) && (getTask(*ptr)->status != EMPTY)) { *ptr = 1; } else {