1 /*
\83}
\83\8b\83`
\83^
\83X
\83N
\8aÖ
\8cW */
5 struct TASKCTL *taskctl;
6 struct TIMER *task_timer;
8 struct TASK *task_now(void)
10 struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
11 return tl->tasks[tl->now];
14 void task_add(struct TASK *task)
16 struct TASKLEVEL *tl = &taskctl->level[task->level];
17 tl->tasks[tl->running] = task;
19 task->flags = 2; /*
\93®
\8dì
\92\86 */
23 void task_remove(struct TASK *task)
26 struct TASKLEVEL *tl = &taskctl->level[task->level];
28 /* task
\82ª
\82Ç
\82±
\82É
\82¢
\82é
\82©
\82ð
\92T
\82· */
29 for (i = 0; i < tl->running; i++) {
30 if (tl->tasks[i] == task) {
31 /*
\82±
\82±
\82É
\82¢
\82½ */
38 tl->now--; /*
\82¸
\82ê
\82é
\82Ì
\82Å
\81A
\82±
\82ê
\82à
\82 \82í
\82¹
\82Ä
\82¨
\82 */
40 if (tl->now >= tl->running) {
41 /* now
\82ª
\82¨
\82©
\82µ
\82È
\92l
\82É
\82È
\82Á
\82Ä
\82¢
\82½
\82ç
\81A
\8fC
\90³
\82·
\82é */
44 task->flags = 1; /*
\83X
\83\8a\81[
\83v
\92\86 */
47 for (; i < tl->running; i++) {
48 tl->tasks[i] = tl->tasks[i + 1];
54 void task_switchsub(void)
57 /*
\88ê
\94Ô
\8fã
\82Ì
\83\8c\83x
\83\8b\82ð
\92T
\82· */
58 for (i = 0; i < MAX_TASKLEVELS; i++) {
59 if (taskctl->level[i].running > 0) {
60 break; /*
\8c©
\82Â
\82©
\82Á
\82½ */
64 taskctl->lv_change = 0;
75 struct TASK *task_init(struct MEMMAN *memman)
78 struct TASK *task, *idle;
79 struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
81 taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL));
82 for (i = 0; i < MAX_TASKS; i++) {
83 taskctl->tasks0[i].flags = 0;
84 taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
85 taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8;
86 set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
87 set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT);
89 for (i = 0; i < MAX_TASKLEVELS; i++) {
90 taskctl->level[i].running = 0;
91 taskctl->level[i].now = 0;
95 task->flags = 2; /*
\93®
\8dì
\92\86\83}
\81[
\83N */
96 task->priority = 2; /* 0.02
\95b */
97 task->level = 0; /*
\8dÅ
\8d\82\83\8c\83x
\83\8b */
99 task_switchsub(); /*
\83\8c\83x
\83\8b\90Ý
\92è */
101 task_timer = timer_alloc();
102 timer_settime(task_timer, task->priority);
105 idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
106 idle->tss.eip = (int) &task_idle;
107 idle->tss.es = 1 * 8;
108 idle->tss.cs = 2 * 8;
109 idle->tss.ss = 1 * 8;
110 idle->tss.ds = 1 * 8;
111 idle->tss.fs = 1 * 8;
112 idle->tss.gs = 1 * 8;
113 task_run(idle, MAX_TASKLEVELS - 1, 1);
118 struct TASK *task_alloc(void)
122 for (i = 0; i < MAX_TASKS; i++) {
123 if (taskctl->tasks0[i].flags == 0) {
124 task = &taskctl->tasks0[i];
125 task->flags = 1; /*
\8eg
\97p
\92\86\83}
\81[
\83N */
126 task->tss.eflags = 0x00000202; /* IF = 1; */
127 task->tss.eax = 0; /*
\82Æ
\82è
\82 \82¦
\82¸0
\82É
\82µ
\82Ä
\82¨
\82
\82±
\82Æ
\82É
\82·
\82é */
138 task->tss.iomap = 0x40000000;
143 return 0; /*
\82à
\82¤
\91S
\95\94\8eg
\97p
\92\86 */
146 void task_run(struct TASK *task, int level, int priority)
149 level = task->level; /*
\83\8c\83x
\83\8b\82ð
\95Ï
\8dX
\82µ
\82È
\82¢ */
152 task->priority = priority;
155 if (task->flags == 2 && task->level != level) { /*
\93®
\8dì
\92\86\82Ì
\83\8c\83x
\83\8b\82Ì
\95Ï
\8dX */
156 task_remove(task); /*
\82±
\82ê
\82ð
\8eÀ
\8ds
\82·
\82é
\82Æflags
\82Í1
\82É
\82È
\82é
\82Ì
\82Å
\89º
\82Ìif
\82à
\8eÀ
\8ds
\82³
\82ê
\82é */
158 if (task->flags != 2) {
159 /*
\83X
\83\8a\81[
\83v
\82©
\82ç
\8bN
\82±
\82³
\82ê
\82é
\8fê
\8d\87 */
164 taskctl->lv_change = 1; /*
\8e\9f\89ñ
\83^
\83X
\83N
\83X
\83C
\83b
\83`
\82Ì
\82Æ
\82«
\82É
\83\8c\83x
\83\8b\82ð
\8c©
\92¼
\82· */
168 void task_sleep(struct TASK *task)
170 struct TASK *now_task;
171 if (task->flags == 2) {
172 /*
\93®
\8dì
\92\86\82¾
\82Á
\82½
\82ç */
173 now_task = task_now();
174 task_remove(task); /*
\82±
\82ê
\82ð
\8eÀ
\8ds
\82·
\82é
\82Æflags
\82Í1
\82É
\82È
\82é */
175 if (task == now_task) {
176 /*
\8e©
\95ª
\8e©
\90g
\82Ì
\83X
\83\8a\81[
\83v
\82¾
\82Á
\82½
\82Ì
\82Å
\81A
\83^
\83X
\83N
\83X
\83C
\83b
\83`
\82ª
\95K
\97v */
178 now_task = task_now(); /*
\90Ý
\92è
\8cã
\82Å
\82Ì
\81A
\81u
\8c»
\8dÝ
\82Ì
\83^
\83X
\83N
\81v
\82ð
\8b³
\82¦
\82Ä
\82à
\82ç
\82¤ */
179 farjmp(0, now_task->sel);
185 void task_switch(void)
187 struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
188 struct TASK *new_task, *now_task = tl->tasks[tl->now];
190 if (tl->now == tl->running) {
193 if (taskctl->lv_change != 0) {
195 tl = &taskctl->level[taskctl->now_lv];
197 new_task = tl->tasks[tl->now];
198 timer_settime(task_timer, new_task->priority);
199 if (new_task != now_task) {
200 farjmp(0, new_task->sel);