mirror of
https://github.com/yourtion/30dayMakeOS.git
synced 2026-05-09 23:13:07 +08:00
205 lines
4.7 KiB
C
205 lines
4.7 KiB
C
/* <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;
|
||
}
|