sched.c

Go to the documentation of this file.
00001 /*****************************************************************************************
00002  Copyright (c) 2002-2004 The UbixOS Project
00003  All rights reserved.
00004 
00005  Redistribution and use in source and binary forms, with or without modification, are
00006  permitted provided that the following conditions are met:
00007 
00008  Redistributions of source code must retain the above copyright notice, this list of
00009  conditions, the following disclaimer and the list of authors.  Redistributions in binary
00010  form must reproduce the above copyright notice, this list of conditions, the following
00011  disclaimer and the list of authors in the documentation and/or other materials provided
00012  with the distribution. Neither the name of the UbixOS Project nor the names of its
00013  contributors may be used to endorse or promote products derived from this software
00014  without specific prior written permission.
00015 
00016  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00017  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
00019  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00021  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00022  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
00023  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00024  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025 
00026  $Id$
00027 
00028 *****************************************************************************************/
00029 
00030 #include <ubixos/sched.h>
00031 #include <ubixos/kpanic.h>
00032 #include <ubixos/spinlock.h>
00033 #include <ubixos/endtask.h>
00034 #include <ubixos/vitals.h>
00035 #include <vfs/mount.h>
00036 #include <lib/kmalloc.h>
00037 #include <lib/kprintf.h>
00038 #include <vmm/vmm.h>
00039 #include <sys/gdt.h>
00040 #include <sys/idt.h>
00041 #include <sys/kern_descrip.h>
00042 #include <isa/8259.h>
00043 #include <string.h>
00044 #include <assert.h>
00045 
00046 #include <ubixos/spinlock.h>
00047 
00048 static kTask_t *taskList = 0x0;
00049 static kTask_t *delList  = 0x0;
00050 static uInt32  nextID    = -1;
00051 
00052 kTask_t *_current = 0x0;
00053 kTask_t *_usedMath = 0x0;
00054 
00055 static spinLock_t schedulerSpinLock = SPIN_LOCK_INITIALIZER;
00056 
00057 /************************************************************************
00058 
00059 Function: int sched_init()
00060 
00061 Description: This function is used to enable the kernel scheduler
00062 
00063 Notes:
00064 
00065 02/20/2004 - Approved for quality
00066 
00067 ************************************************************************/
00068 
00069 
00070 int sched_init() {        
00071   taskList = (kTask_t *)kmalloc(sizeof(kTask_t));
00072   if(taskList == 0x0)
00073         kpanic("Unable to create task list");
00074    
00075   taskList->id = nextID++;
00076 
00077   /* Print out information on scheduler */
00078   kprintf("sched0 - Address: [0x%X]\n", taskList);
00079         
00080   /* Return so we know everything went well */
00081   return(0x0); 
00082   }
00083 
00084 
00085 void sched(){
00086   uInt32 memAddr   = 0x0;
00087   kTask_t *tmpTask = 0x0;
00088   kTask_t *delTask = 0x0;
00089   
00090   if (!spinTryLock(&schedulerSpinLock))
00091         return;
00092   
00093   tmpTask = _current->next;
00094   //outportByte(0xE9,_current->id + '0');
00095   schedStart:
00096 
00097   /* Yield the next task from the current prio queue */
00098   for (;tmpTask != 0x0; tmpTask = tmpTask->next) {
00099     if (tmpTask->state > 0x0) {
00100       _current = tmpTask;
00101       if (_current->state == FORK)
00102         _current->state = READY;
00103       break;
00104       }
00105     else if (tmpTask->state == DEAD)
00106       {
00107         delTask  = tmpTask;
00108         tmpTask  = tmpTask->next;
00109         sched_deleteTask(delTask->id);
00110         sched_addDelTask(delTask);
00111         goto schedStart;
00112       }
00113     }
00114 
00115         /* Finished all the tasks, restarting the list */
00116         if (0x0 == tmpTask) {
00117                 tmpTask = taskList;
00118                 goto schedStart;
00119         }
00120         
00121         
00122         if (_current->state > 0x0) {
00123                 if (_current->oInfo.v86Task == 0x1)
00124                         irqDisable(0x0);
00125                 asm("cli");
00126                 memAddr = (uInt32)&(_current->tss);
00127                 ubixGDT[4].descriptor.baseLow  = (memAddr & 0xFFFF);
00128                 ubixGDT[4].descriptor.baseMed  = ((memAddr >> 16) & 0xFF);
00129                 ubixGDT[4].descriptor.baseHigh = (memAddr >> 24);
00130                 ubixGDT[4].descriptor.access   = '\x89';
00131                 spinUnlock(&schedulerSpinLock);
00132                 asm("sti");
00133                 asm("ljmp $0x20,$0\n");
00134         }
00135         else
00136         {
00137                 spinUnlock(&schedulerSpinLock);
00138         }
00139         
00140         return;
00141 }
00142 
00143 
00144 kTask_t *schedNewTask() {
00145   int i = 0;
00146   kTask_t *tmpTask  = (kTask_t *)kmalloc(sizeof(kTask_t));
00147   struct file *fp = 0x0;
00148   if (tmpTask == 0x0)
00149     kpanic("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n");
00150 
00151   memset(tmpTask,0x0,sizeof(kTask_t)); 
00152   /* Filling in tasks attrs */
00153   tmpTask->usedMath   = 0x0;
00154   tmpTask->state      = NEW;
00155 
00156   /* HACK */
00157   for (i=0;i<3;i++) {
00158     fp = kmalloc(sizeof(struct file));
00159     tmpTask->td.o_files[i] = fp;
00160     fp->f_flag = 0x4;
00161     }
00162 
00163   spinLock(&schedulerSpinLock);
00164   tmpTask->id         = nextID++;
00165   tmpTask->next  = taskList;
00166   tmpTask->prev  = 0x0;
00167   taskList->prev = tmpTask;
00168   taskList       = tmpTask;
00169 
00170   spinUnlock(&schedulerSpinLock);
00171   
00172   return(tmpTask);
00173   }
00174 
00175 
00176 int sched_deleteTask(pidType id) {
00177   kTask_t *tmpTask = 0x0; 
00178 
00179   /* Checking each task from the prio queue */
00180   for (tmpTask = taskList; tmpTask != 0x0; tmpTask = tmpTask->next) {
00181    if (tmpTask->id == id) {
00182      if (tmpTask->prev != 0x0)
00183        tmpTask->prev->next = tmpTask->next;
00184      if (tmpTask->next != 0x0)
00185        tmpTask->next->prev = tmpTask->prev;
00186      if (taskList == tmpTask)
00187        taskList = tmpTask->next;
00188       
00189      return(0x0);
00190      }
00191    }
00192   return(0x1);
00193   }
00194   
00195 int  sched_addDelTask(kTask_t *tmpTask) {
00196   tmpTask->next = delList;
00197   tmpTask->prev = 0x0;
00198   if (delList != 0x0)
00199     delList->prev = tmpTask;
00200   delList       = tmpTask;
00201   return(0x0);
00202   }
00203   
00204 kTask_t *sched_getDelTask() {
00205   kTask_t *tmpTask = 0x0;
00206   
00207   if (delList == 0x0)
00208     return(0x0);
00209     
00210   tmpTask = delList;
00211   delList = delList->next;
00212   return(tmpTask);
00213   }
00214 
00215 
00216 kTask_t * 
00217 schedFindTask(uInt32 id) 
00218 {
00219         kTask_t *tmpTask = 0x0; 
00220 
00221         for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) {
00222                 if (tmpTask->id == id)
00223                         return(tmpTask);
00224         }
00225 
00226         return(0x0);
00227 }
00228 
00229 
00230 /************************************************************************
00231 
00232  Function: void schedEndTask()
00233 
00234  Description: This function will end a task
00235 
00236  Notes:
00237 
00238   02/20/2004 - Approved for quality
00239 
00240 ************************************************************************/
00241 void 
00242 schedEndTask(pidType pid) {
00243         endTask(_current->id);
00244         sched_yield();
00245 }
00246 
00247 /************************************************************************
00248 
00249 Function: int schedEndTask()
00250 
00251 Description: This function will yield a task 
00252 
00253 Notes:
00254 
00255 02/20/2004 - Approved for quality
00256 
00257 ************************************************************************/
00258 
00259 void 
00260 sched_yield() {
00261   sched();
00262   }
00263 
00264 /*
00265 asm(
00266   ".globl sched_yield \n"
00267   "sched_yield:       \n"
00268   "  cli              \n"
00269   "  call sched       \n"
00270   );
00271 */
00272 
00273 /************************************************************************
00274 
00275 Function: int sched_setStatus(pidType pid,tState state)
00276 
00277 Description: Change the tasks status
00278 
00279 Notes:
00280 
00281 ************************************************************************/
00282 int sched_setStatus(pidType pid,tState state) {
00283   kTask_t *tmpTask = schedFindTask(pid);
00284   if (tmpTask == 0x0)
00285     return(0x1);
00286   tmpTask->state = state;
00287   return(0x0);
00288   }
00289 
00290 /***
00291  END
00292  ***/
00293 

Generated on Sun Dec 3 02:38:04 2006 for UbixOS V2 by  doxygen 1.4.7