OSDN Git Service

AI003:config.txt, words.txtを追加。
[chnosproject/CHNOSProject.git] / CHNOSProject / chnos / tolset_chn_000 / chnos_008 / chnos / mtask.c
1 \r
2 #include "core.h"\r
3 \r
4 UI_TaskControl *taskctl;\r
5 \r
6 void task_init(void)\r
7 {\r
8         int i;\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
14         }\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
18         }\r
19 \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
30 \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
36         task_switchsub();\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
40         return;\r
41 }\r
42 \r
43 UI_Task *task_alloc(void)\r
44 {\r
45         int i;\r
46         UI_Task *task;\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
52                         task->tss.eax = 0;\r
53                         task->tss.ecx = 0;\r
54                         task->tss.edx = 0;\r
55                         task->tss.ebx = 0;\r
56                         task->tss.ebp = 0;\r
57                         task->tss.esi = 0;\r
58                         task->tss.edi = 0;\r
59                         task->tss.es = 0;\r
60                         task->tss.ds = 0;\r
61                         task->tss.fs = 0;\r
62                         task->tss.gs = 0;\r
63                         task->tss.ldtr = 0;\r
64                         task->tss.iomap = 0x40000000;\r
65                         task->tss.ss0 = 0;\r
66                         task->tss.cr3 = 0x00400000;\r
67                         return task;\r
68                 }\r
69         }\r
70         return 0;\r
71 }\r
72 \r
73 void task_run(UI_Task *task, int level, int priority)\r
74 {\r
75         if(level < 0){\r
76                 level = task->level;\r
77         }\r
78         if(priority > 0) {\r
79                 task->priority = priority;\r
80         }\r
81         if(task->flags == inuse && task->level != level)task_remove(task);\r
82         if(task->flags != inuse){\r
83                 task->level = level;\r
84                 task_add(task);\r
85         }\r
86         taskctl->change_lv_next = true;\r
87         return;\r
88 }\r
89 \r
90 void task_switch(void)\r
91 {\r
92         UI_Task *new_task, *now_task = taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];\r
93 \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
101         }\r
102         return;\r
103 }\r
104 \r
105 void task_sleep(UI_Task *task)\r
106 {\r
107         UI_Task *now_task;\r
108         int eflags;\r
109 \r
110         eflags = io_load_eflags();\r
111         io_cli();\r
112 \r
113         if(task->flags == inuse){\r
114                 now_task = task_now();\r
115                 task_remove(task);\r
116                 if(task == now_task){\r
117                         task_switchsub();\r
118                         now_task = task_now();\r
119                         farjmp(0, now_task->selector);\r
120                 }\r
121         }\r
122 \r
123         io_store_eflags(eflags);\r
124 \r
125         return;\r
126 }\r
127 \r
128 void task_arguments(UI_Task *task, int args, ...)\r
129 {\r
130         int i;\r
131         va_list ap;\r
132 \r
133         va_start(ap, args);\r
134         \r
135         task->tss.esp -= 4 * (args + 1);\r
136 \r
137         for(i = 1; i < args + 1; i++){\r
138                 *((int *)(task->tss.esp + (i * 4))) = va_arg(ap, int);\r
139         }\r
140         va_end(ap);\r
141         return; \r
142 }\r
143 \r
144 UI_Task *task_now(void)\r
145 {\r
146         return taskctl->level[taskctl->level_now].tasks[taskctl->level[taskctl->level_now].task_now];\r
147 }\r
148 \r
149 void task_add(UI_Task *task)\r
150 {\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
154         return; \r
155 }\r
156 \r
157 void task_remove(UI_Task *task)\r
158 {\r
159         int i;\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
162         }\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
169         }\r
170         return;\r
171 }\r
172 \r
173 void task_switchsub(void)\r
174 {\r
175         int i;\r
176         for(i = 0; i < MAX_LEVELS; i++){\r
177                 if(taskctl->level[i].running_tasks > 0) break;\r
178         }\r
179         taskctl->level_now = i;\r
180         taskctl->change_lv_next = false;\r
181         return;\r
182 }\r
183 \r
184 void task_idle(void)\r
185 {\r
186         for(;;){\r
187                 io_hlt();\r
188         }\r
189 }\r