UbixOS V2 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
50 kTask_t *_current = 0x0;
51 kTask_t *_usedMath = 0x0;
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
136 kTask_t *schedNewTask() {
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
196 kTask_t *sched_getDelTask() {
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
207 kTask_t *
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