/**************************************************************************************
Copyright (c) 2002 The UbixOS Project
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are prohibited.
$Id$
**************************************************************************************/
#include <ubixos/schedule.h>
#include <ubixos/io.h>
#include <ubixos/gdt.h>
#include <ubixos/idt.h>
#include <drivers/8259.h>
int currentProc;
struct taskStruct taskList[numTasks];
struct taskStruct *_current,*_usedMath = 0x0;
extern union descriptorTableunion GDT[7];
extern int testVal;
/* Initialize Scheduler */
void initScheduler(void) {
int i;
for (i=0;i<numTasks;i++) {
taskList[i].id = i;
taskList[i].status = AVAILABLE;
taskList[i].usedMath = 0;
taskList[i].cpuTime = 0;
taskList[i].uid = -1;
taskList[i].gid = -1;
}
currentProc = -1;
setVector(timerInt, mVec, (dInt + dPresent + dDpl3));
}
/* Finds A Free Task */
int findTask() {
int i;
for (i=0;i<numTasks;i++) {
if (taskList[i].status == AVAILABLE) {
return(i);
}
}
return(-1);
}
void schedule() {
int i,proc = -1,memAddr;
outportByte(0x20, 0x20);
for (i=currentProc;i<numTasks;i++) {
if (taskList[i].status == RUNABLE) {
proc = i;
break;
}
else if ((taskList[i].status == ACTIVE) && (i != currentProc)) {
proc = i;
break;
}
if (i+1 >= numTasks) { i = -1; }
}
if (proc != -1) {
currentProc = proc;
_current = &taskList[proc];
taskList[proc].status = ACTIVE;
taskList[proc].cpuTime++;
memAddr = (unsigned int)&taskList[proc].tss;
GDT[4].descriptor.access = 0x89;
GDT[4].descriptor.baseLow = (memAddr & 0xFFFF);
GDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xff);
GDT[4].descriptor.baseHigh = (memAddr >> 24);
asm("ljmp $0x20,$0\n");
}
}
/* Timer Interupt */
asm (
".globl timerInt \n"
"timerInt: \n"
" pusha \n"
" call schedule \n"
" popa \n"
" iret \n"
);