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/>.
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 ? */
33 unsigned task_id
= NULL
;
37 static void wait (void)
41 for(wait
= WAIT
; wait
!= 0; wait
--)
45 int cstrcmp (char *one
, char *two
)
49 for(i
= 0; (unsigned) i
< strlen (one
); i
++)
55 if ((two
[i
] == ' ' || two
[i
] == '\0') || two
[i
] == '\n')
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;
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
89 else /* you type normal text */
91 currtty
->shell
[currtty
->shell_len
] = key
;
92 currtty
->shell_len
++;
105 /*****************************************************************************
106 *****************************************************************************/
113 //puts ("thread1\n");
118 unsigned task_shell ()
125 //puts ("thread0\n");
140 * Function, which handle each task.
141 * It jump from task to another task in moment, when schedule () is called.
148 /* handle console on kernel level */
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
)
168 if(setjmp (_curr_task
->state
)) /* set current task */
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 */
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 */
197 /* alloc and init context */
198 task
= (task_t
*) kmalloc (sizeof (task_t
));
201 /* mark task #0 (idle task) runnable */
202 task
->status
= TS_RUNNABLE
;
204 task
->priority
= priority
;
206 strcpy (task
->name
, name
);
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 */
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;
228 task
->status
= TS_RUNNABLE
;
229 // task priority - how offten will be active
230 task
->priority
= priority
;
232 strcpy (task
->name
, name
);
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
);
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))
253 /*if (!task_create ("shell", (unsigned) task_shell, 50))
256 if (!task_create ("fdd", (unsigned) fdd_task, 25))