4 UI_TaskControl *taskctl;
\r
9 taskctl = (UI_TaskControl *)sys_memman_alloc(sizeof(UI_TaskControl));
\r
10 for(i = 0; i < MAX_TASKS; i++){
\r
11 taskctl->tasks0[i].flags = initialized;
\r
12 taskctl->tasks0[i].selector = (TASK_GDT_START + i) * 8;
\r
13 set_segmdesc(system.io.mem.segment.gdt + TASK_GDT_START + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32);
\r
15 for(i = 0; i < MAX_LEVELS; i++){
\r
16 taskctl->level[i].running_tasks = 0;
\r
17 taskctl->level[i].task_now = 0;
\r
20 system.ui.task.idle = task_alloc();
\r
21 system.ui.task.idle->tss.esp = (int)sys_memman_alloc(64 * 1024) + 64 * 1024;
\r
22 system.ui.task.idle->tss.eip = (int)&task_idle;
\r
23 system.ui.task.idle->tss.es = 1 * 8;
\r
24 system.ui.task.idle->tss.cs = 2 * 8;
\r
25 system.ui.task.idle->tss.ss = 1 * 8;
\r
26 system.ui.task.idle->tss.ds = 1 * 8;
\r
27 system.ui.task.idle->tss.fs = 1 * 8;
\r
28 system.ui.task.idle->tss.gs = 1 * 8;
\r
29 task_run(system.ui.task.idle, MAX_LEVELS - 1, 1);
\r
31 system.ui.task.main = task_alloc();
\r
32 system.ui.task.main->flags = inuse;
\r
33 system.ui.task.main->priority = 2; /*0.02sec*/
\r
34 system.ui.task.main->level = 0;
\r
35 task_add(system.ui.task.main);
\r
37 load_tr(system.ui.task.main->selector);
\r
38 system.ui.timer.taskswitch = timer_alloc();
\r
39 timer_settime(system.ui.timer.taskswitch, system.ui.task.main->priority);
\r
43 UI_Task *task_alloc(void)
\r
47 for(i = 0; i < MAX_TASKS; i++){
\r
48 if(taskctl->tasks0[i].flags == initialized){
\r
49 task = &taskctl->tasks0[i];
\r
50 task->flags = allocated;
\r
51 task->tss.eflags = 0x00000202;
\r
64 task->tss.iomap = 0x40000000;
\r
66 task->tss.cr3 = 0x00400000;
\r
73 void task_run(UI_Task *task, int level, int priority)
\r
76 level = task->level;
\r
79 task->priority = priority;
\r
81 if(task->flags == inuse && task->level != level)task_remove(task);
\r
82 if(task->flags != inuse){
\r
83 task->level = level;
\r
86 taskctl->change_lv_next = true;
\r
90 void task_switch(void)
\r
92 UI_Task *new_task, *now_task = taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];
\r
94 taskctl->level[taskctl->level_now].task_now++;
\r
95 if(taskctl->level[taskctl->level_now].task_now == taskctl->level[taskctl->level_now].running_tasks) taskctl->level[taskctl->level_now].task_now = 0;
\r
96 if(taskctl->change_lv_next) task_switchsub();
\r
97 new_task = taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];
\r
98 timer_settime(system.ui.timer.taskswitch, new_task->priority);
\r
99 if(new_task != now_task){
\r
100 farjmp(0, new_task->selector);
\r
105 void task_sleep(UI_Task *task)
\r
110 eflags = io_load_eflags();
\r
113 if(task->flags == inuse){
\r
114 now_task = task_now();
\r
116 if(task == now_task){
\r
118 now_task = task_now();
\r
119 farjmp(0, now_task->selector);
\r
123 io_store_eflags(eflags);
\r
128 void task_arguments(UI_Task *task, int args, ...)
\r
133 va_start(ap, args);
\r
135 task->tss.esp -= 4 * (args + 1);
\r
137 for(i = 1; i < args + 1; i++){
\r
138 *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);
\r
144 UI_Task *task_now(void)
\r
146 return taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];
\r
149 void task_add(UI_Task *task)
\r
151 taskctl->level[task->level].tasks[taskctl->level[task->level].running_tasks] = task;
\r
152 taskctl->level[task->level].running_tasks++;
\r
153 task->flags = inuse;
\r
157 void task_remove(UI_Task *task)
\r
160 for(i = 0; i < taskctl->level[task->level].running_tasks; i++){
\r
161 if(taskctl->level[task->level].tasks[i] == task) break;
\r
163 taskctl->level[task->level].running_tasks--;
\r
164 if(i < taskctl->level[task->level].task_now) taskctl->level[task->level].task_now--;
\r
165 if(taskctl->level[task->level].task_now >= taskctl->level[task->level].running_tasks) taskctl->level[task->level].task_now = 0;
\r
166 task->flags = allocated;
\r
167 for(; i < taskctl->level[task->level].running_tasks; i++){
\r
168 taskctl->level[task->level].tasks[i] = taskctl->level[task->level].tasks[i + 1];
\r
173 void task_switchsub(void)
\r
176 for(i = 0; i < MAX_LEVELS; i++){
\r
177 if(taskctl->level[i].running_tasks > 0) break;
\r
179 taskctl->level_now = i;
\r
180 taskctl->change_lv_next = false;
\r
184 void task_idle(void)
\r