Newer
Older
ubixos / src / sys / kernel / schedule.c
/**************************************************************************************
 Copyright (c) 2002
      The UbixOS Project

 $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;
    }
  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;
    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"
  );