static void taskscheduler(void) {//协程调度函数 int i; Task *t; taskdebug("scheduler enter"); for(;;){ if(taskcount == 0) exit(taskexitval); t = taskrunqueue.head;//从头部开始唤起 if(t == nil){ fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount); exit(1); } deltask(&taskrunqueue, t);//从待调度链表中移出来,调度它运行 t->ready = 0; taskrunning = t;//标记正在执行的协程 tasknswitch++; taskdebug("run %d (%s)", t->id, t->name); contextswitch(&taskschedcontext, &t->context);//真正进行上下文切换,这样就切换到了其他协程运行,比如taskmainstart //print("back in scheduler\n"); taskrunning = nil;//把刚刚被切换的协程的指向改为空。 if(t->exiting){ if(!t->system) taskcount--; i = t->alltaskslot; alltask[i] = alltask[--nalltask]; alltask[i]->alltaskslot = i; free(t); } } }
static void taskscheduler(void) { int i; Task *t; taskdebug("scheduler enter"); for(;;){ if(taskcount == 0) exit(taskexitval); t = taskrunqueue.head; if(t == nil){ fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount); exit(1); } deltask(&taskrunqueue, t); t->ready = 0; taskrunning = t; tasknswitch++; taskdebug("run %d (%s)", t->id, t->name); contextswitch(&taskschedcontext, &t->context); //print("back in scheduler\n"); taskrunning = (Task*) nil; if(t->exiting){ if(!t->system) taskcount--; i = t->alltaskslot; alltask[i] = alltask[--nalltask]; alltask[i]->alltaskslot = i; free(t); } } }
static void taskscheduler(void) { int i; Task *t; for (; ;) { if (taskcount == 0) exit(taskexitval); t = taskrunqueue.head; if (t == nil) { fprintf(stderr, "no runnable tasks! %d tasks stalled\n", taskcount); exit(1); } deltask(&taskrunqueue, t); t->ready = 0; taskrunning = t; tasknswitch++; contextswitch(&taskschedcontext, &t->context); taskrunning = nil; if (t->exiting) { if (!t->system) taskcount--; i = t->alltaskslot; alltask[i] = alltask[--nalltask]; alltask[i]->alltaskslot = i; free(t); } } }
static void taskscheduler(void) { int i; Task *t; taskdebug("scheduler enter"); for(;;){ // 当前除了系统协程外没有其他协程, 退出 if(taskcount == 0) exit(taskexitval); // 处理的顺序是 FIFO t = taskrunqueue.head; if(t == nil){ fprint(2, "no runnable tasks! %d tasks stalled\n", taskcount); exit(1); } // 从就绪队列里面去掉这个协程 deltask(&taskrunqueue, t); t->ready = 0; // 把拿出来的就绪任务设置为当前正在执行的任务 taskrunning = t; // 协程调度计数 +1 tasknswitch++; taskdebug("run %d (%s)", t->id, t->name); // 切换到刚拿到的协程, 调度的核心 // 使用 taskschedcontext 保留老的堆栈状态, 把 t->context 设置为新的执行上下文 // 后面通过 taskswitch 切换回调度协程 contextswitch(&taskschedcontext, &t->context); //print("back in scheduler\n"); taskrunning = nil; if(t->exiting){ // 协程执行完退出 // 系统协程不计数 if(!t->system) taskcount--; // 把数组中最后一个任务放到要删除的任务的位置 // 这里判断一下当前任务是不是已经在数据尾部会更加优雅? i = t->alltaskslot; alltask[i] = alltask[--nalltask]; alltask[i]->alltaskslot = i; // 释放任务 free(t); } } }
static DECL_SYMBOL_ACTION(emulate_reset_computer) { /* Upon restart, save volatile RAMs and reload all ROMs, in case they were overwritten by a bug or something. ;) */ if (task == csa_WRITE) { memory_volatile_save(); memory_complete_load(); stateflag &= ~ST_INTERRUPT; reset9901(); init9900(); hold9900pin(INTPIN_RESET); contextswitch(0); } return 1; }
// 协程切换 void taskswitch(void) { needstack(0); contextswitch(&taskrunning->context, &taskschedcontext); }
void taskswitch(void) {//主动进行协程切换,其实就是切换到main协程,到那里去进行实际的切换 needstack(0);//检测堆栈溢出 contextswitch(&taskrunning->context, &taskschedcontext); }