struct _task *task_init(struct _memman *memman) { int i; struct _task *task; struct _segmdes *gdt = (struct _segmdes *) ADR_GDT; taskctl = (struct _taskctl *) memman_alloc_4k(memman, sizeof (struct _taskctl)); taskctl->now_lv = 0; taskctl->lv_change = 0; for (i = 0; i < MAX_TASKS; i++) { /* Register all task slots on segment descriptor table */ taskctl->tasks0[i].flags = TASK_UNUSED; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* Setup selector (GDT segment) number */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* Allocate new task for task_init caller */ task = task_alloc(); task->flags = TASK_RUNNING; /* Priority and level */ task->priority = 2; /* Timeslice = 10ms * pri */ task->level = 0; /* Highest Level */ /* Add task to level control */ task_add(task); /* Recalebrate Running Level */ task_switchsub(); /* Activate Current Task */ load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task; 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; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; task->priority = 2; task->level = 0; task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
/* will be directly called by inthandler20 */ void task_switch(void) { struct TASKLEVEL *tl = &taskctl->level[taskctl->now_lv]; struct TASK *new_task, *now_task = tl->tasks[tl->now]; /* why can't we use this?? tl->now = (tl->now + 1) % (tl->running); */ tl->now++; if (tl->now == tl->running) { tl->now = 0; } /* need to make sure we are runnig the curret task, update correct running level */ if(taskctl->lv_change != 0) { task_switchsub(); tl = &taskctl->level[taskctl->now_lv]; } new_task = tl->tasks[tl->now]; /* align time slice to new task now */ timer_settime(task_timer, new_task->priority); /* if it's not the same task jump to the new task */ if(new_task != now_task) { farjmp(0, new_task->sel); } return; }
void task_sleep(task_t* task) { task_t* 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); } } }
void task_sleep(struct TASK *task) { struct TASK *now_task; if (task->flags == 2) { // if specified task is waken now_task = task_now(); task_remove (task); if (task == now_task) { task_switchsub (); now_task = task_now (); farjmp (0, now_task->sel); } } return; }
void task_sleep(TASK* task) { if (task->flags != RUNNING) return; // TODO: Need to prevent interrupt? TASK* now_task = task_now(); task_remove(task); // This makes the task ALLOCATED (sleep). if (task == now_task) { // Sleep by self => need task switch. task_switchsub(); now_task = task_now(); farjmp(0, now_task->sel); } }
/* 使某任务睡眠 */ void task_sleep(struct TASK *task) { struct TASK *now_task; if (task->flags == 2) { /* 如果处于活动状态 */ now_task = task_now(); /* 获得当前正在运行的任务的task指针 */ task_remove(task); /* 执行词语句的话flag会等于1 */ if (task == now_task) { /* 如果是让自己休眠 则需要任务切换 */ task_switchsub(); now_task = task_now(); /* 在设定后获取新的level中待运行的任务 */ farjmp(0, now_task->sel); /* 切换任务 */ } } 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; }
/* init taskctl and allocate the first task to the thread that calls the init method we don't need to assign it a fifo because all it doesn't is to switch by calling farjmp() and doesn't need to put data to any buffer */ 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].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].flags = 0; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); } /* initialize all levels */ for(i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* after initializaing all tasks in taskctl, we need to alloc the first task and assign it to the thread that calls init */ task = task_alloc(); task->flags = 2; /* running */ task->priority = 2; task->level = 0; /* the first task(for mouse/keyboard/timer interruption) should be in highest level */ task_add(task); task_switchsub(); /* update taskctl->now_lv */ /* set task register to current task */ load_tr(task->sel); idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8; 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; /* the idle task will always be running at lowest level in case there's no when there's no active task to run and OS doesn't know where to jump */ task_run(idle, MAX_TASKLEVELS - 1, 1); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
/* remove task from its level */ void task_sleep(struct TASK *task) { struct TASK *current_task; /* if the task is running then we remove it from running buffer and mark it as not running */ if(task->flags == 2) { current_task = task_now(); /*task->flags would become 1 */ task_remove(task); /* if a task is termination it self, need to explicitly jump to the new running task */ if(task == current_task) { task_switchsub(); current_task = task_now(); farjmp(0, current_task->sel); } } return; }
/** * @description 休眠任务 * @param task:欲休眠的任务 * @notice 休眠任务自己将会引起任务切换 */ void task_sleep(struct TASK *task){ struct TASK *now_task; //TODO 任务有效性检查 if (task->flags == 2) { now_task = task_now(); task_remove(task); if (task == now_task) { //TODO 当前任务,则立即休眠 task_switchsub(); //TODO 获得跳转的目标任务,以跳转 now_task = task_now(); farjmp(0, now_task->sel); } } return; }
/** * @description 任务调度 */ 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; }
////将该任务从可裕兴队列中移除,同时设置为参数指定的状态 //参数:task -- 需要操作的任务, task_status -- task被设成这个任务状态 static void _task_change_status(struct TASK *task, enum TASK_STATUS task_status) { struct TASK *now_task; if (task->flags == TASK_STATUS_RUNNING) { /* 如果处于活动状态 */ now_task = task_now(); task_remove(task, task_status); if (task == now_task) { /* 如果是让自己休眠,则需要进行任务切换 */ task_switchsub(); now_task = task_now(); /* 在设定后获取当前任务的值 */ //debug("process[%d,%s] go to sleep, process[%d,%s] is running",task->pid,task->name,now_task->pid,now_task->name); farjmp(0, now_task->sel); } } return; }
/** * @description 初始化 * @param menman:内存地址 */ 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)); //TODO 初始化所有任务 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } //TODO 初始化所有优先级层 for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; // task->priority = 2; //0.02秒 task->level = 0; //最高级别 task_add(task); task_switchsub(); //切换 load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); //TODO 初始化空闲进程 idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; //X86的栈是向下增长的,所以需要+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_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)); /* 初始化所有的任务的task结构 */ for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* 选择子初始化 */ /* 描述符初始化 */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } /* 初始化所有level结构 */ for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; /* 没有正在运行的任务 */ taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02秒 */ task->level = 0; /* 最高LEVEL */ task_add(task); task_switchsub(); /* LEVEL设置 */ load_tr(task->sel); /* 修改tr寄存器 */ 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; }
void task_sleep(struct _task *task) { struct _task *now_task; if (task->flags == TASK_RUNNING) { /* If current task is running */ now_task = task_now(); /* Set 'task' back to READY state */ task_remove(task); /* Sleep yourself */ if (task == now_task) { /* Recalebrate Level */ task_switchsub(); /* Switch Current Task */ now_task = task_now(); /* JMP */ farjmp(0, now_task->sel); } } return; }
void task_switch(void) { if (taskctl->now_lv >= MAX_TASKLEVELS) { io_stihlt(); return; } TASKLEVEL* tl = &taskctl->level[taskctl->now_lv]; TASK* now_task = tl->tasks[tl->now++]; if (tl->now >= tl->running) tl->now = 0; if (taskctl->lv_change) { task_switchsub(); tl = &taskctl->level[taskctl->now_lv]; } TASK* new_task = tl->tasks[tl->now]; timer_settime(task_timer, new_task->priority); if (new_task != now_task) farjmp(0, new_task->sel); }
/* 该函数只在void inthandler20(int *esp)时钟中断处理中被调用 */ 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) { /* 当now出现异常时调整它 */ tl->now = 0; } if (taskctl->lv_change != 0) { /* 是否需要检测level */ task_switchsub(); /* 寻找最上层的level */ tl = &taskctl->level[taskctl->now_lv]; /* 修改tl让它指向最上层的level */ } new_task = tl->tasks[tl->now]; timer_settime(task_timer, new_task->priority); if (new_task != now_task) { farjmp(0, new_task->sel); } return; }
void TaskControll::task_switch(void){ TaskLevel *tl = &TaskControll::level[TaskControll::now_lv]; Task *now_task = tl->tasks[tl->now]; Task *new_task; tl->now++; if(tl->now == tl->running){ tl->now = 0; } //タスクレベルの切り替え if(TaskControll::lv_change != 0){ task_switchsub(); tl = &TaskControll::level[TaskControll::now_lv]; } new_task = tl->tasks[tl->now]; TaskControll::timer->settime(new_task->priority); //実際のタスクの切り替え if(new_task != now_task){ farjmp(0,new_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]; /* Switch to current level:next task */ tl->now++; /* Reset to beginning when proceed to the end */ if (tl->now == tl->running) { tl->now = 0; } /* If it requires level switching */ if (taskctl->lv_change != 0) { task_switchsub(); tl = &taskctl->level[taskctl->now_lv]; } new_task = tl->tasks[tl->now]; /* Timeslice allocation depends on its priority */ timer_settime(task_timer, new_task->priority); /* Only do JMP when there is different task */ if (new_task != now_task) { farjmp(0, new_task->sel); } return; }
TASK* task_init(MEMMAN* memman) { SEGMENT_DESCRIPTOR* gdt = (SEGMENT_DESCRIPTOR*)ADR_GDT; taskctl = (TASKCTL*)memman_alloc_4k(memman, sizeof(TASKCTL)); for (int 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 (int i = 0; i < MAX_TASKLEVELS; ++i) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } TASK* task = task_alloc(); // Main task. task->flags = RUNNING; task->priority = 2; // 0.02 sec task->level = 0; // Max level. task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); TASK* idle = task_alloc(); idle->tss.esp = (int)memman_alloc_4k(memman, 256) + 256; idle->tss.eip = (int)&task_idle; idle->tss.es = idle->tss.ss = idle->tss.ds = idle->tss.fs = idle->tss.gs = 1 * 8; idle->tss.cs = 2 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); taskctl->task_fpu = NULL; return task; }
task_t* task_init(memman_t* memman) { int i; task_t *task, *idle; segment_descriptor* gdt = (segment_descriptor*)ADR_GDT; taskctl = (taskctl_t*)memman_alloc_4k(memman, sizeof(taskctl_t)); 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); } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02s */ task->level = 0; /* 最高等级 */ task_add(task); task_switchsub(); /* 设置等级 */ 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; }
////初始化进程管理器 //返回:内核进程task_a struct TASK *task_init(struct MEMMAN *memman) { int i,j; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); //事先将全部的TASK结构的TSS和LDT、文件描述符都设置好 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].pid = -1; taskctl->tasks0[i].forked = 0; strcpy(taskctl->tasks0[i].name,"anony"); taskctl->tasks0[i].flags = 0; //标志未使用 taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; //设置TSS的seletor, 当进行任务切换的时候,是跳转到这个段上的。 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); //TSS段 set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT); //LDT段 //设置任务的文件描述符 for(j=0; j<NR_FILES; j++){ taskctl->tasks0[i].filp[j] = 0; } /* TODO: 初始化进程的键盘输入缓冲,这里的内存可能没有被释放*/ int bufCount = 100; int *fifobuf = (int *)memman_alloc(memman,sizeof(int)*bufCount); taskctl->tasks0[i].ch_buf.task = &taskctl->tasks0[i]; fifo32_init(&taskctl->tasks0[i].ch_buf, bufCount, fifobuf, 0); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02秒 */ task->level = 0; /* 最高LEVEL */ task_add(task); task_switchsub(); /* LEVEL设置 */ 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; strcpy(idle->name,"idle"); task_run(idle, MAX_TASKLEVELS - 1, 1); //默认情况下,所有进程的父进程都是idle,包括task_a和idle自己。 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[0].parent_pid = idle->pid; } return task; }