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: sched_8c-source.html 88 2016-01-12 00:11:29Z reddawg $
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 <vfs/mount.h>
00035 #include <lib/kmalloc.h>
00036 #include <lib/kprintf.h>
00037 #include <vmm/vmm.h>
00038 #include <sys/gdt.h>
00039 #include <sys/idt.h>
00040 #include <sys/kern_descrip.h>
00041 #include <isa/8259.h>
00042 #include <string.h>
00043 #include <assert.h>
00044 
00045 #include <ubixos/spinlock.h>
00046 
00047 static kTask_t *taskList = 0x0;
00048 static kTask_t *delList  = 0x0;
00049 static uInt32  nextID    = -1;
00050 
00051 kTask_t *_current = 0x0;
00052 kTask_t *_usedMath = 0x0;
00053 
00054 static spinLock_t schedulerSpinLock = SPIN_LOCK_INITIALIZER;
00055 
00056 /************************************************************************
00057 
00058 Function: int sched_init()
00059 
00060 Description: This function is used to enable the kernel scheduler
00061 
00062 Notes:
00063 
00064 02/20/2004 - Approved for quality
00065 
00066 ************************************************************************/
00067 
00068 
00069 int sched_init() {        
00070   taskList = (kTask_t *)kmalloc(sizeof(kTask_t));
00071   if(taskList == 0x0)
00072         kpanic("Unable to create task list");
00073    
00074   taskList->id = nextID++;
00075 
00076   /* Print out information on scheduler */
00077   kprintf("sched0 - Address: [0x%X]\n", taskList);
00078         
00079   /* Return so we know everything went well */
00080   return(0x0); 
00081   }
00082 
00083 
00084 void sched(){
00085   uInt32 memAddr   = 0x0;
00086   kTask_t *tmpTask = 0x0;
00087   kTask_t *delTask = 0x0;
00088   
00089   if (!spinTryLock(&schedulerSpinLock))
00090         return;
00091   
00092   tmpTask = _current->next;
00093   //outportByte(0xE9,_current->id + '0');
00094   schedStart:
00095 
00096   /* Yield the next task from the current prio queue */
00097   for (;tmpTask != 0x0; tmpTask = tmpTask->next) {
00098     if (tmpTask->state > 0x0) {
00099       _current = tmpTask;
00100       if (_current->state == FORK)
00101         _current->state = READY;
00102       break;
00103       }
00104     else if (tmpTask->state == DEAD)
00105       {
00106         delTask  = tmpTask;
00107         tmpTask  = tmpTask->next;
00108         sched_deleteTask(delTask->id);
00109         sched_addDelTask(delTask);
00110         goto schedStart;
00111       }
00112     }
00113 
00114         /* Finished all the tasks, restarting the list */
00115         if (0x0 == tmpTask) {
00116                 tmpTask = taskList;
00117                 goto schedStart;
00118         }
00119         
00120         
00121         if (_current->state > 0x0) {
00122                 if (_current->oInfo.v86Task == 0x1)
00123                         irqDisable(0x0);
00124                 asm("cli");
00125                 memAddr = (uInt32)&(_current->tss);
00126                 ubixGDT[4].descriptor.baseLow  = (memAddr & 0xFFFF);
00127                 ubixGDT[4].descriptor.baseMed  = ((memAddr >> 16) & 0xFF);
00128                 ubixGDT[4].descriptor.baseHigh = (memAddr >> 24);
00129                 ubixGDT[4].descriptor.access   = '\x89';
00130                 spinUnlock(&schedulerSpinLock);
00131                 asm("sti");
00132                 asm("ljmp $0x20,$0\n");
00133         }
00134         else
00135         {
00136                 spinUnlock(&schedulerSpinLock);
00137         }
00138         
00139         return;
00140 }
00141 
00142 
00143 kTask_t *schedNewTask() {
00144   int i = 0;
00145   kTask_t *tmpTask  = (kTask_t *)kmalloc(sizeof(kTask_t));
00146   struct file *fp = 0x0;
00147   if (tmpTask == 0x0)
00148     kpanic("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n");
00149 
00150   memset(tmpTask,0x0,sizeof(kTask_t)); 
00151   /* Filling in tasks attrs */
00152   tmpTask->usedMath   = 0x0;
00153   tmpTask->state      = NEW;
00154 
00155   /* HACK */
00156   for (i=0;i<3;i++) {
00157     fp = kmalloc(sizeof(struct file));
00158     tmpTask->td.o_files[i] = (uint32_t)fp;
00159     fp->f_flag = 0x4;
00160     }
00161 
00162   spinLock(&schedulerSpinLock);
00163   tmpTask->id         = nextID++;
00164   tmpTask->next  = taskList;
00165   tmpTask->prev  = 0x0;
00166   taskList->prev = tmpTask;
00167   taskList       = tmpTask;
00168 
00169   spinUnlock(&schedulerSpinLock);
00170   
00171   return(tmpTask);
00172   }
00173 
00174 
00175 int sched_deleteTask(pidType id) {
00176   kTask_t *tmpTask = 0x0; 
00177 
00178   /* Checking each task from the prio queue */
00179   for (tmpTask = taskList; tmpTask != 0x0; tmpTask = tmpTask->next) {
00180    if (tmpTask->id == id) {
00181      if (tmpTask->prev != 0x0)
00182        tmpTask->prev->next = tmpTask->next;
00183      if (tmpTask->next != 0x0)
00184        tmpTask->next->prev = tmpTask->prev;
00185      if (taskList == tmpTask)
00186        taskList = tmpTask->next;
00187       
00188      return(0x0);
00189      }
00190    }
00191   return(0x1);
00192   }
00193   
00194 int  sched_addDelTask(kTask_t *tmpTask) {
00195   tmpTask->next = delList;
00196   tmpTask->prev = 0x0;
00197   if (delList != 0x0)
00198     delList->prev = tmpTask;
00199   delList       = tmpTask;
00200   return(0x0);
00201   }
00202   
00203 kTask_t *sched_getDelTask() {
00204   kTask_t *tmpTask = 0x0;
00205   
00206   if (delList == 0x0)
00207     return(0x0);
00208     
00209   tmpTask = delList;
00210   delList = delList->next;
00211   return(tmpTask);
00212   }
00213 
00214 
00215 kTask_t * 
00216 schedFindTask(uInt32 id) 
00217 {
00218         kTask_t *tmpTask = 0x0; 
00219 
00220         for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) {
00221                 if (tmpTask->id == id)
00222                         return(tmpTask);
00223         }
00224 
00225         return(0x0);
00226 }
00227 
00228 
00229 /************************************************************************
00230 
00231  Function: void schedEndTask()
00232 
00233  Description: This function will end a task
00234 
00235  Notes:
00236 
00237   02/20/2004 - Approved for quality
00238 
00239 ************************************************************************/
00240 void 
00241 schedEndTask(pidType pid) {
00242         endTask(_current->id);
00243         sched_yield();
00244 }
00245 
00246 /************************************************************************
00247 
00248 Function: int schedEndTask()
00249 
00250 Description: This function will yield a task 
00251 
00252 Notes:
00253 
00254 02/20/2004 - Approved for quality
00255 
00256 ************************************************************************/
00257 
00258 void 
00259 sched_yield() {
00260   sched();
00261   }
00262 
00263 /*
00264 asm(
00265   ".globl sched_yield \n"
00266   "sched_yield:       \n"
00267   "  cli              \n"
00268   "  call sched       \n"
00269   );
00270 */
00271 
00272 /************************************************************************
00273 
00274 Function: int sched_setStatus(pidType pid,tState state)
00275 
00276 Description: Change the tasks status
00277 
00278 Notes:
00279 
00280 ************************************************************************/
00281 int sched_setStatus(pidType pid,tState state) {
00282   kTask_t *tmpTask = schedFindTask(pid);
00283   if (tmpTask == 0x0)
00284     return(0x1);
00285   tmpTask->state = state;
00286   return(0x0);
00287   }
00288 
00289 /***
00290  END
00291  ***/
00292 

Generated on Fri Dec 15 11:18:55 2006 for UbixOS V2 by  doxygen 1.4.7