Files
30dayMakeOS/30_day/haribote/mtask.c
Yourtion 0e31ff06ca bug fix
2016-05-20 14:27:07 +08:00

205 lines
4.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* <20>}<7D><><EFBFBD>`<60>^<5E>X<EFBFBD>N<EFBFBD>֌W */
#include "bootpack.h"
struct TASKCTL *taskctl;
struct TIMER *task_timer;
struct TASK *task_now(void)
{
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
return tl->tasks[tl->now];
}
void task_add(struct TASK *task)
{
struct TASKLEVEL *tl = &taskctl->level[task->level];
tl->tasks[tl->running] = task;
tl->running++;
task->flags = 2; /* <20><><EFBFBD>쒆 */
return;
}
void task_remove(struct TASK *task)
{
int i;
struct TASKLEVEL *tl = &taskctl->level[task->level];
/* task<73><6B><EFBFBD>ǂ<EFBFBD><C782>ɂ<EFBFBD><C982><EFBFBD><E982A9>T<EFBFBD><54> */
for (i = 0; i < tl->running; i++) {
if (tl->tasks[i] == task) {
/* <20><><EFBFBD><EFBFBD><EFBFBD>ɂ<EFBFBD><C982><EFBFBD> */
break;
}
}
tl->running--;
if (i < tl->now) {
tl->now--; /* <20><><EFBFBD><EFBFBD><EFBFBD>̂ŁA<C581><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD> */
}
if (tl->now >= tl->running) {
/* now<6F><77><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȓl<C892>ɂȂ<C982><C882>Ă<EFBFBD><C482><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
tl->now = 0;
}
task->flags = 1; /* <20>X<EFBFBD><58><EFBFBD>[<5B>v<EFBFBD><76> */
/* <20><><EFBFBD>炵 */
for (; i < tl->running; i++) {
tl->tasks[i] = tl->tasks[i + 1];
}
return;
}
void task_switchsub(void)
{
int i;
/* <20><>ԏ<EFBFBD>̃<EFBFBD><CC83>x<EFBFBD><78><EFBFBD><EFBFBD>T<EFBFBD><54> */
for (i = 0; i < MAX_TASKLEVELS; i++) {
if (taskctl->level[i].running > 0) {
break; /* <20><><EFBFBD>‚<EFBFBD><C282><EFBFBD><EFBFBD><EFBFBD> */
}
}
taskctl->now_lv = i;
taskctl->lv_change = 0;
return;
}
void task_idle(void)
{
for (;;) {
io_hlt();
}
}
struct TASK *task_init(struct MEMMAN *memman)
{
int i;
struct TASK *task, *idle;
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL));
for (i = 0; i < MAX_TASKS; i++) {
taskctl->tasks0[i].flags = 0;
taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8;
set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT);
}
for (i = 0; i < MAX_TASKLEVELS; i++) {
taskctl->level[i].running = 0;
taskctl->level[i].now = 0;
}
task = task_alloc();
task->flags = 2; /* <20><><EFBFBD><EFBFBD>}<7D>[<5B>N */
task->priority = 2; /* 0.02<EFBFBD>b */
task->level = 0; /* <20>ō<EFBFBD><C58D><EFBFBD><EFBFBD>x<EFBFBD><78> */
task_add(task);
task_switchsub(); /* <20><><EFBFBD>x<EFBFBD><78><EFBFBD>ݒ<EFBFBD> */
load_tr(task->sel);
task_timer = timer_alloc();
timer_settime(task_timer, task->priority);
idle = task_alloc();
idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
idle->tss.eip = (int) &task_idle;
idle->tss.es = 1 * 8;
idle->tss.cs = 2 * 8;
idle->tss.ss = 1 * 8;
idle->tss.ds = 1 * 8;
idle->tss.fs = 1 * 8;
idle->tss.gs = 1 * 8;
task_run(idle, MAX_TASKLEVELS - 1, 1);
return task;
}
struct TASK *task_alloc(void)
{
int i;
struct TASK *task;
for (i = 0; i < MAX_TASKS; i++) {
if (taskctl->tasks0[i].flags == 0) {
task = &taskctl->tasks0[i];
task->flags = 1; /*正在使用的标志*/
task->tss.eflags = 0x00000202; /* IF = 1; */
task->tss.eax = 0; /*这里先置为0*/
task->tss.ecx = 0;
task->tss.edx = 0;
task->tss.ebx = 0;
task->tss.ebp = 0;
task->tss.esi = 0;
task->tss.edi = 0;
task->tss.es = 0;
task->tss.ds = 0;
task->tss.fs = 0;
task->tss.gs = 0;
task->tss.iomap = 0x40000000;
task->tss.ss0 = 0;
return task;
}
}
return 0; /*全部正在使用*/
}
void task_run(struct TASK *task, int level, int priority)
{
if (level < 0) {
level = task->level; /*不改变LEVEL */
}
if (priority > 0) {
task->priority = priority;
}
if (task->flags == 2 && task->level != level) {
/*改变活动中的LEVEL */
task_remove(task); /*这里执行之后flag的值会变为1于是下面的if语句块也会被执行*/
}
if (task->flags != 2) {
/*从休眠状态唤醒的情形*/
task->level = level;
task_add(task);
}
taskctl->lv_change = 1; /*下次任务切换时检查LEVEL */
return;
}
void task_sleep(struct TASK *task)
{
struct TASK *now_task;
if (task->flags == 2) {
/*如果处于活动状态*/
now_task = task_now();
task_remove(task); /*执行此语句的话flags将变为1 */
if (task == now_task) {
/*如果是让自己休眠,则需要进行任务切换*/
task_switchsub();
now_task = task_now(); /*在设定后获取当前任务的值*/
farjmp(0, now_task->sel);
}
}
return;
}
void task_switch(void)
{
struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv];
struct TASK *new_task, *now_task = tl->tasks[tl->now];
tl->now++;
if (tl->now == tl->running) {
tl->now = 0;
}
if (taskctl->lv_change != 0) {
task_switchsub();
tl = &taskctl->level[taskctl->now_lv];
}
new_task = tl->tasks[tl->now];
timer_settime(task_timer, new_task->priority);
if (new_task != now_task) {
farjmp(0, new_task->sel);
}
return;
}