Nothing
[ZeXOS.git] / kernel / sched.c
blobac92e1932b766e18bd2ecf5d85fcea033d7ab0ac
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <system.h>
21 #include <x86.h>
22 #include <string.h>
23 #include <setjmp.h>
25 /* jmp_buf (E)IP and (E)SP register names for various environments:
26 Tinylib TurboC DJGPP Linux (glibc5) */
27 #define JMPBUF_IP eip /* j_ip __eip __pc */
28 #define JMPBUF_SP esp /* j_sp __esp __sp */
29 #define JMPBUF_FLAGS eflags /* j_flag __eflags ? */
31 task_t task_list;
32 task_t *_curr_task;
33 unsigned task_id = NULL;
35 #define WAIT 0xFFFFFL
37 static void wait (void)
39 unsigned long wait;
41 for(wait = WAIT; wait != 0; wait--)
42 /* nothing */;
45 int cstrcmp (char *one, char *two)
47 int i;
49 for(i = 0; (unsigned) i < strlen (one); i ++)
51 if (one[i] != two[i])
52 return -1;
55 if ((two[i] == ' ' || two[i] == '\0') || two[i] == '\n')
56 return 0;
58 return -2;
62 int gets (void)
64 if (key != 0)
67 int i = 0;
68 settextcolor (2,0);
70 char c[1];
71 c[0] = key;
72 tty_write (currtty, c, 1);
74 if (key == '\n') // we press enter
76 currtty->shell[currtty->shell_len] = '\0';
77 currtty->shell_len = 0;
78 i = 1;
80 else
82 /* if you has wroted some text, and backspace is pressed, lets move cursor back */
83 if (key == '\b' && currtty->shell_len > 0)
85 currtty->shell_len --; // first we have to descrease text length
86 currtty->shell[currtty->shell_len] = '\0'; // we can put \0 character under cursor
87 //putch (' ');
89 else /* you type normal text */
91 currtty->shell[currtty->shell_len] = key;
92 currtty->shell_len ++;
96 key = 0;
97 settextcolor (15, 0);
99 return i;
102 return 0;
105 /*****************************************************************************
106 *****************************************************************************/
108 void fdd_task (void)
110 while(1)
112 schedule();
113 //puts ("thread1\n");
114 wait();
118 unsigned task_shell ()
120 int i;
122 while(1)
124 schedule ();
125 //puts ("thread0\n");
126 /*i = gets ();
128 if (i == 1) {
129 if (curruser)
130 console (i);
131 else
132 getlogin (i);
135 wait ();
139 /** SCHEDULE
140 * Function, which handle each task.
141 * It jump from task to another task in moment, when schedule () is called.
144 int ticks = 0;
145 void schedule (void)
148 /* handle console on kernel level */
149 int i = gets ();
151 if (i == 1) {
152 if (currtty->user)
153 console (i);
154 else
155 getlogin (i);
158 /* handle all other tasks */
159 ticks ++; /* increase ticks count */
160 if (ticks > 100) /* tasks has priority 0-100% */
161 ticks = 0; /* null ticks counter, we start again */
164 if (_curr_task->priority) /* is it on kernel level ? No ? Let's continue */
165 if ((100 - _curr_task->priority) < ticks)
166 return;
168 if(setjmp (_curr_task->state)) /* set current task */
169 return;
171 while (1) {
172 _curr_task = _curr_task->next; /* continue on next task */
174 if (_curr_task == &task_list) /* task is out of task_list structure */
175 _curr_task = task_list.next; /* current task is first task in task_list structure */
177 if (_curr_task->status == TS_RUNNABLE) { /* Is current task running ? */
178 timer_wait (1); /* prevent before kernel freeze or stack fault */
179 longjmp (_curr_task->state, 1); /* long jump to task function */
180 return;
185 /*****************************************************************************
186 *****************************************************************************/
188 unsigned task_create (char *name, unsigned entry, unsigned priority)
190 task_id ++; // increase new task
192 if (priority > 100) /* priority 100 is max */
193 priority = 100;
195 task_t *task;
197 /* alloc and init context */
198 task = (task_t *) kmalloc (sizeof (task_t));
200 if (entry == NULL) {
201 /* mark task #0 (idle task) runnable */
202 task->status = TS_RUNNABLE;
204 task->priority = priority;
205 // add name of task
206 strcpy (task->name, name);
208 /* add into list */
209 task->next = &task_list;
210 task->prev = task_list.prev;
211 task->prev->next = task;
212 task->next->prev = task;
214 /* set _curr_task so schedule() will save state of task #0 */
215 _curr_task = task;
216 return 1;
219 (void) setjmp (task->state);
220 // ...especially the stack pointer
221 unsigned adr = (unsigned) (task->stacks + USER_STACK_SIZE);
222 task->state[0].JMPBUF_SP = adr;
223 // ...and program counter
224 task->state[0].JMPBUF_IP = entry;
225 // set EFLAGS value to enable interrupts
226 task->state[0].JMPBUF_FLAGS = 0x200;
227 // mark it runnable
228 task->status = TS_RUNNABLE;
229 // task priority - how offten will be active
230 task->priority = priority;
231 // add name of task
232 strcpy (task->name, name);
234 /* add into list */
235 task->next = &task_list;
236 task->prev = task_list.prev;
237 task->prev->next = task;
238 task->next->prev = task;
240 kprintf ("task -> %s (%d)\n", name, task_id);
242 return 1;
245 unsigned int init_tasks (void)
247 task_list.next = &task_list;
248 task_list.prev = &task_list;
250 if (!task_create ("kernel", NULL, 0))
251 return 0;
253 /*if (!task_create ("shell", (unsigned) task_shell, 50))
254 return 0;
256 if (!task_create ("fdd", (unsigned) fdd_task, 25))
257 return 0;*/
259 return 1;