+++ /dev/null
-\r
-#include "core.h"\r
-\r
-UI_TaskControl *taskctl;\r
-\r
-void task_init(void)\r
-{\r
- int i;\r
- taskctl = (UI_TaskControl *)sys_memman_alloc(sizeof(UI_TaskControl));\r
- for(i = 0; i < MAX_TASKS; i++){\r
- taskctl->tasks0[i].flags = initialized;\r
- taskctl->tasks0[i].selector = (TASK_GDT_START + i) * 8;\r
- set_segmdesc(system.io.mem.segment.gdt + TASK_GDT_START + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32);\r
- }\r
- for(i = 0; i < MAX_LEVELS; i++){\r
- taskctl->level[i].running_tasks = 0;\r
- taskctl->level[i].task_now = 0;\r
- }\r
-\r
- system.ui.task.idle = task_alloc();\r
- system.ui.task.idle->tss.esp = (int)sys_memman_alloc(64 * 1024) + 64 * 1024;\r
- system.ui.task.idle->tss.eip = (int)&task_idle;\r
- system.ui.task.idle->tss.es = 1 * 8;\r
- system.ui.task.idle->tss.cs = 2 * 8;\r
- system.ui.task.idle->tss.ss = 1 * 8;\r
- system.ui.task.idle->tss.ds = 1 * 8;\r
- system.ui.task.idle->tss.fs = 1 * 8;\r
- system.ui.task.idle->tss.gs = 1 * 8;\r
- task_run(system.ui.task.idle, MAX_LEVELS - 1, 1);\r
-\r
- system.ui.task.main = task_alloc();\r
- system.ui.task.main->flags = inuse;\r
- system.ui.task.main->priority = 2; /*0.02sec*/\r
- system.ui.task.main->level = 0;\r
- task_add(system.ui.task.main);\r
- task_switchsub();\r
- load_tr(system.ui.task.main->selector);\r
- system.ui.timer.taskswitch = timer_alloc();\r
- timer_settime(system.ui.timer.taskswitch, system.ui.task.main->priority);\r
- return;\r
-}\r
-\r
-UI_Task *task_alloc(void)\r
-{\r
- int i;\r
- UI_Task *task;\r
- for(i = 0; i < MAX_TASKS; i++){\r
- if(taskctl->tasks0[i].flags == initialized){\r
- task = &taskctl->tasks0[i];\r
- task->flags = allocated;\r
- task->tss.eflags = 0x00000202;\r
- task->tss.eax = 0;\r
- task->tss.ecx = 0;\r
- task->tss.edx = 0;\r
- task->tss.ebx = 0;\r
- task->tss.ebp = 0;\r
- task->tss.esi = 0;\r
- task->tss.edi = 0;\r
- task->tss.es = 0;\r
- task->tss.ds = 0;\r
- task->tss.fs = 0;\r
- task->tss.gs = 0;\r
- task->tss.ldtr = 0;\r
- task->tss.iomap = 0x40000000;\r
- task->tss.ss0 = 0;\r
- task->tss.cr3 = 0x00400000;\r
- return task;\r
- }\r
- }\r
- return 0;\r
-}\r
-\r
-void task_run(UI_Task *task, int level, int priority)\r
-{\r
- if(level < 0){\r
- level = task->level;\r
- }\r
- if(priority > 0) {\r
- task->priority = priority;\r
- }\r
- if(task->flags == inuse && task->level != level)task_remove(task);\r
- if(task->flags != inuse){\r
- task->level = level;\r
- task_add(task);\r
- }\r
- taskctl->change_lv_next = true;\r
- return;\r
-}\r
-\r
-void task_switch(void)\r
-{\r
- UI_Task *new_task, *now_task = taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];\r
-\r
- taskctl->level[taskctl->level_now].task_now++;\r
- if(taskctl->level[taskctl->level_now].task_now == taskctl->level[taskctl->level_now].running_tasks) taskctl->level[taskctl->level_now].task_now = 0;\r
- if(taskctl->change_lv_next) task_switchsub();\r
- new_task = taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];\r
- timer_settime(system.ui.timer.taskswitch, new_task->priority);\r
- if(new_task != now_task){\r
- farjmp(0, new_task->selector);\r
- }\r
- return;\r
-}\r
-\r
-void task_sleep(UI_Task *task)\r
-{\r
- UI_Task *now_task;\r
- int eflags;\r
-\r
- eflags = io_load_eflags();\r
- io_cli();\r
-\r
- if(task->flags == inuse){\r
- now_task = task_now();\r
- task_remove(task);\r
- if(task == now_task){\r
- task_switchsub();\r
- now_task = task_now();\r
- farjmp(0, now_task->selector);\r
- }\r
- }\r
-\r
- io_store_eflags(eflags);\r
-\r
- return;\r
-}\r
-\r
-void task_arguments(UI_Task *task, int args, ...)\r
-{\r
- int i;\r
- va_list ap;\r
-\r
- va_start(ap, args);\r
- \r
- task->tss.esp -= 4 * (args + 1);\r
-\r
- for(i = 1; i < args + 1; i++){\r
- *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);\r
- }\r
- va_end(ap);\r
- return; \r
-}\r
-\r
-UI_Task *task_now(void)\r
-{\r
- return taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];\r
-}\r
-\r
-void task_add(UI_Task *task)\r
-{\r
- taskctl->level[task->level].tasks[taskctl->level[task->level].running_tasks] = task;\r
- taskctl->level[task->level].running_tasks++;\r
- task->flags = inuse;\r
- return; \r
-}\r
-\r
-void task_remove(UI_Task *task)\r
-{\r
- int i;\r
- for(i = 0; i < taskctl->level[task->level].running_tasks; i++){\r
- if(taskctl->level[task->level].tasks[i] == task) break;\r
- }\r
- taskctl->level[task->level].running_tasks--;\r
- if(i < taskctl->level[task->level].task_now) taskctl->level[task->level].task_now--;\r
- if(taskctl->level[task->level].task_now >= taskctl->level[task->level].running_tasks) taskctl->level[task->level].task_now = 0;\r
- task->flags = allocated;\r
- for(; i < taskctl->level[task->level].running_tasks; i++){\r
- taskctl->level[task->level].tasks[i] = taskctl->level[task->level].tasks[i + 1];\r
- }\r
- return;\r
-}\r
-\r
-void task_switchsub(void)\r
-{\r
- int i;\r
- for(i = 0; i < MAX_LEVELS; i++){\r
- if(taskctl->level[i].running_tasks > 0) break;\r
- }\r
- taskctl->level_now = i;\r
- taskctl->change_lv_next = false;\r
- return;\r
-}\r
-\r
-void task_idle(void)\r
-{\r
- for(;;){\r
- io_hlt();\r
- }\r
-}\r