UbixOS  2.0
sched.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2002-2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <ubixos/sched.h>
30 #include <ubixos/kpanic.h>
31 #include <ubixos/spinlock.h>
32 #include <ubixos/endtask.h>
33 #include <vfs/mount.h>
34 #include <lib/kmalloc.h>
35 #include <lib/kprintf.h>
36 #include <vmm/vmm.h>
37 #include <sys/gdt.h>
38 #include <sys/idt.h>
39 #include <isa/8259.h>
40 #include <string.h>
41 #include <assert.h>
42 #include <sys/descrip.h>
43 
44 #include <ubixos/spinlock.h>
45 
46 static kTask_t *taskList = 0x0;
47 static kTask_t *delList = 0x0;
48 static uInt32 nextID = -1;
49 
52 
53 static struct spinLock schedulerSpinLock = SPIN_LOCK_INITIALIZER;
54 
55 /************************************************************************
56 
57  Function: int sched_init()
58 
59  Description: This function is used to enable the kernel scheduler
60 
61  Notes:
62 
63  02/20/2004 - Approved for quality
64 
65  ************************************************************************/
66 
67 int sched_init() {
68  taskList = (kTask_t *) kmalloc(sizeof(kTask_t));
69  if (taskList == 0x0)
70  kpanic("Unable to create task list");
71 
72  taskList->id = nextID++;
73 
74  /* Print out information on scheduler */
75  kprintf("sched0 - Address: [0x%X]\n", taskList);
76 
77  /* Return so we know everything went well */
78  return (0x0);
79 }
80 
81 void sched() {
82  uInt32 memAddr = 0x0;
83  kTask_t *tmpTask = 0x0;
84  kTask_t *delTask = 0x0;
85 
86  if (!spinTryLock(&schedulerSpinLock))
87  return;
88 
89  tmpTask = _current->next;
90  //outportByte(0xE9,_current->id + '0');
91  schedStart:
92 
93  /* Yield the next task from the current prio queue */
94  for (; tmpTask != 0x0; tmpTask = tmpTask->next) {
95  if (tmpTask->state > 0x0) {
96  _current = tmpTask;
97  if (_current->state == FORK)
98  _current->state = READY;
99  break;
100  }
101  else if (tmpTask->state == DEAD) {
102  delTask = tmpTask;
103  tmpTask = tmpTask->next;
104  sched_deleteTask(delTask->id);
105  sched_addDelTask(delTask);
106  goto schedStart;
107  }
108  }
109 
110  /* Finished all the tasks, restarting the list */
111  if (0x0 == tmpTask) {
112  tmpTask = taskList;
113  goto schedStart;
114  }
115 
116  if (_current->state > 0x0) {
117  if (_current->oInfo.v86Task == 0x1)
118  irqDisable(0x0);
119  asm("cli");
120  memAddr = (uInt32) &(_current->tss);
121  ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF);
122  ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF);
123  ubixGDT[4].descriptor.baseHigh = (memAddr >> 24);
124  ubixGDT[4].descriptor.access = '\x89';
125  spinUnlock(&schedulerSpinLock);
126  asm("sti");
127  asm("ljmp $0x20,$0\n");
128  }
129  else {
130  spinUnlock(&schedulerSpinLock);
131  }
132 
133  return;
134 }
135 
137  int i = 0;
138  kTask_t *tmpTask = (kTask_t *) kmalloc(sizeof(kTask_t));
139  struct file *fp = 0x0;
140  if (tmpTask == 0x0)
141  kpanic("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n");
142 
143  memset(tmpTask, 0x0, sizeof(kTask_t));
144  /* Filling in tasks attrs */
145  tmpTask->usedMath = 0x0;
146  tmpTask->state = NEW;
147 
148  /* HACK */
149  for (i = 0; i < 3; i++) {
150  fp = (void *) kmalloc(sizeof(struct file));
151  tmpTask->td.o_files[i] = (uint32_t) fp;
152  fp->f_flag = 0x4;
153  }
154 
155 
156  spinLock(&schedulerSpinLock);
157  tmpTask->id = nextID++;
158  tmpTask->next = taskList;
159  tmpTask->prev = 0x0;
160  taskList->prev = tmpTask;
161  taskList = tmpTask;
162 
163  spinUnlock(&schedulerSpinLock);
164 
165  return (tmpTask);
166 }
167 
168 int sched_deleteTask(pidType id) {
169  kTask_t *tmpTask = 0x0;
170 
171  /* Checking each task from the prio queue */
172  for (tmpTask = taskList; tmpTask != 0x0; tmpTask = tmpTask->next) {
173  if (tmpTask->id == id) {
174  if (tmpTask->prev != 0x0)
175  tmpTask->prev->next = tmpTask->next;
176  if (tmpTask->next != 0x0)
177  tmpTask->next->prev = tmpTask->prev;
178  if (taskList == tmpTask)
179  taskList = tmpTask->next;
180 
181  return (0x0);
182  }
183  }
184  return (0x1);
185 }
186 
187 int sched_addDelTask(kTask_t *tmpTask) {
188  tmpTask->next = delList;
189  tmpTask->prev = 0x0;
190  if (delList != 0x0)
191  delList->prev = tmpTask;
192  delList = tmpTask;
193  return (0x0);
194 }
195 
197  kTask_t *tmpTask = 0x0;
198 
199  if (delList == 0x0)
200  return (0x0);
201 
202  tmpTask = delList;
203  delList = delList->next;
204  return (tmpTask);
205 }
206 
208 schedFindTask(uInt32 id) {
209  kTask_t *tmpTask = 0x0;
210 
211  for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) {
212  if (tmpTask->id == id)
213  return (tmpTask);
214  }
215 
216  return (0x0);
217 }
218 
219 /************************************************************************
220 
221  Function: void schedEndTask()
222 
223  Description: This function will end a task
224 
225  Notes:
226 
227  02/20/2004 - Approved for quality
228 
229  ************************************************************************/
230 void schedEndTask(pidType pid) {
231  endTask(_current->id);
232  sched_yield();
233 }
234 
235 /************************************************************************
236 
237  Function: int schedEndTask()
238 
239  Description: This function will yield a task
240 
241  Notes:
242 
243  02/20/2004 - Approved for quality
244 
245  ************************************************************************/
246 
247 void sched_yield() {
248  sched();
249 }
250 
251 /*
252  asm(
253  ".globl sched_yield \n"
254  "sched_yield: \n"
255  " cli \n"
256  " call sched \n"
257  );
258  */
259 
260 /************************************************************************
261 
262  Function: int sched_setStatus(pidType pid,tState state)
263 
264  Description: Change the tasks status
265 
266  Notes:
267 
268  ************************************************************************/
269 int sched_setStatus(pidType pid, tState state) {
270  kTask_t *tmpTask = schedFindTask(pid);
271  if (tmpTask == 0x0)
272  return (0x1);
273  tmpTask->state = state;
274  return (0x0);
275 }
276 
277 /***
278  END
279  ***/
280 
8259.h
taskStruct
Definition: sched.h:62
spinlock.h
gdt.h
sched_addDelTask
int sched_addDelTask(kTask_t *tmpTask)
Definition: sched.c:186
descriptorTableUnion::descriptor
struct gdtDescriptor descriptor
Definition: gdt.h:84
uInt32
unsigned long int uInt32
Definition: objgfx30.h:49
ubixGDT
union descriptorTableUnion ubixGDT[11]
_usedMath
kTask_t * _usedMath
Definition: sched.c:51
schedEndTask
void schedEndTask(pidType pid)
Definition: sched.c:228
thread::o_files
void * o_files[512]
Definition: thread.h:42
string.h
idt.h
file::f_flag
uint32_t f_flag
Definition: descrip.h:68
NEW
Definition: sched.h:47
irqDisable
void irqDisable(uInt16 irqNo)
file
Definition: descrip.h:67
taskStruct::prev
struct taskStruct * prev
Definition: sched.h:65
assert.h
spinUnlock
void spinUnlock(spinLock_t *lock)
Definition: spinlock.c:36
vmm.h
endtask.h
taskStruct::tss
struct tssStruct tss
Definition: sched.h:67
sched_init
int sched_init()
Definition: sched.c:66
SPIN_LOCK_INITIALIZER
#define SPIN_LOCK_INITIALIZER
Definition: spinlock.h:36
FORK
Definition: sched.h:47
sched.h
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
gdtDescriptor::access
unsigned char access
Definition: gdt.h:70
taskStruct::td
struct thread td
Definition: sched.h:78
spinLock
void spinLock(spinLock_t *lock)
Definition: spinlock.c:55
kpanic.h
taskStruct::id
pidType id
Definition: sched.h:63
schedFindTask
kTask_t * schedFindTask(uInt32 id)
Definition: sched.c:207
kprintf.h
uint32_t
__uint32_t uint32_t
Definition: types.h:46
osInfo::v86Task
uInt8 v86Task
Definition: sched.h:52
taskStruct::usedMath
uInt16 usedMath
Definition: sched.h:76
DEAD
Definition: sched.h:47
taskStruct::next
struct taskStruct * next
Definition: sched.h:66
endTask
void endTask(pidType)
Definition: endtask.c:44
_current
kTask_t * _current
Definition: sched.c:50
sched_setStatus
int sched_setStatus(pidType pid, tState state)
Definition: sched.c:265
pidType
int pidType
Definition: types.h:75
schedNewTask
kTask_t * schedNewTask()
Definition: sched.c:135
gdtDescriptor::baseLow
unsigned short baseLow
Definition: gdt.h:68
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
spinLock
Definition: spinlock.h:41
taskStruct::state
tState state
Definition: sched.h:72
descrip.h
memset
void * memset(void *dst, int c, size_t length)
gdtDescriptor::baseMed
unsigned char baseMed
Definition: gdt.h:69
gdtDescriptor::baseHigh
unsigned char baseHigh
Definition: gdt.h:73
READY
Definition: sched.h:47
mount.h
kprintf
int kprintf(const char *,...)
Definition: kprintf.c:259
sched_deleteTask
int sched_deleteTask(pidType id)
Definition: sched.c:167
spinTryLock
int spinTryLock(spinLock_t *lock)
Definition: spinlock.c:47
kmalloc.h
taskStruct::oInfo
struct osInfo oInfo
Definition: sched.h:69
sched_getDelTask
kTask_t * sched_getDelTask()
Definition: sched.c:195
tState
tState
Definition: sched.h:46
sched
void sched()
Definition: sched.c:80
sched_yield
void sched_yield()
Definition: sched.c:244